标签:
Output one integer number — the number of ways to organize the diversion.
6 7 1 2 1 2 3 1 1 4 0 3 4 1 4 5 1 3 6 0 5 6 1
4
题意 : 给出两种边 0 , 1 , 1是可以构成树的 。问删除0 , 1 边各一条 , 能否把图分割开 。
先对 边1构成的树进行树剖 , 再看看有多少条 0 边经过 某条 1 边的路径上 , 没有的话可以任意选 0 边, 有的话只能有1条0边, 答案更新1
#include <bits/stdc++.h> using namespace std ; const int N = 20010; const int M = 400010 ; int n , m ; int eh[N] , et[M] , nxt[M] , tot ; int top[N] , fa[N] , dep[N] , num[N] , p[N] , fp[N] , son[N] ; int pos ; void addedge( int u , int v ) { et[tot] = v , nxt[tot] = eh[u] , eh[u] = tot++ ; et[tot] = u , nxt[tot] = eh[v] , eh[v] = tot++ ; } void dfs1( int u , int pre , int d ) { dep[u] = d ; fa[u] = pre ; num[u] = 1 ; for( int i = eh[u] ; ~i ; i = nxt[i] ) { int v = et[i] ; if( v == pre ) continue ; dfs1( v , u , d + 1 ) ; num[u] += num[v] ; if( son[u] == -1 || num[v] > num[ son[u] ] ) son[u] = v ; } } void dfs2( int u , int sp ) { top[u] = sp ; p[u] = pos++ ; fp[ p[u] ] = u ; if( son[u] == -1 ) return ; dfs2( son[u] , sp ) ; for( int i = eh[u] ; ~i ; i = nxt[i] ) { int v = et[i] ; if( v == son[u] || v == fa[u] ) continue ; dfs2(v,v) ; } } void init() { tot = 0 ; pos = 1 ; memset( eh , -1 , sizeof eh ) ; memset( son , -1 , sizeof son ) ; } int val[N] ; void Change( int u , int v ) { int f1 = top[u] , f2 = top[v] ; while( f1 != f2 ) { if( dep[f1] < dep[f2] ){ swap(f1,f2); swap(u,v); } val[ p[f1] ] += 1 ; val[ p[u] + 1 ] -= 1 ; u=fa[f1]; f1=top[u]; } if( dep[u] > dep[v] ) swap(u,v); val[ p[ son[u] ] ] += 1 ; val[ p[v] + 1 ] -= 1 ; } typedef pair<int,int> pii ; #define X first #define Y second vector<pii>Q; int Run() { while( cin >> n >> m ) { memset( val , 0 , sizeof val ) ; init() ; Q.clear() ; int tt = 0 ; while( m-- ) { int u , v , c ; cin >> u >> v >> c ; if( c ) { addedge( u , v ) ; } else { Q.push_back( pii(u,v) ) ; tt++ ; } } dfs1( 1 , 0 , 0 ) , dfs2( 1 , 1 ) ; for( int i = 0 ; i < Q.size() ; ++i ) { Change( Q[i].X , Q[i].Y ) ; } int ans = 0 , t = val[1] ; for( int i = 2 ; i <= n ; ++i ) { t += val[i] ; if( t == 0 ) ans += tt ; else if( t == 1 ) ans++ ; } cout << ans << endl ; } return 0 ; } int main() { ios::sync_with_stdio(0); return Run(); }
ACdream 1424 Diversion( 树链剖分 )
标签:
原文地址:http://www.cnblogs.com/hlmark/p/4502173.html