http://acm.hdu.edu.cn/showproblem.php?pid=2242
const int Max_N = 10008 ; const int Max_M = 20008 ; struct Edge{ int u ; int v ; int next ; }edge[Max_M*4]; int id ; int List[Max_N] , List2[Max_N] ; void add_edge(int u , int v ){ edge[id].u = u ; edge[id].v = v ; edge[id].next = List[u] ; List[u] = id++ ; } void add_edge2(int u , int v){ edge[id].u = u ; edge[id].v = v ; edge[id].next = List2[u] ; List2[u] = id++ ; } int val[Max_N] , sumall , sum[Max_N] , dp[Max_N] ; /*belong[u] , u所在的双连通分量 , color双连通分量个数 */ /*同一个belong[]里的任意2点至少有2条不同的路径*/ int dfsn[Max_N] , low[Max_N] , Time , color , belong[Max_N] ; stack <int> Q ; void tarjan(int u , int father){ int v , e , flag = 1 ; dfsn[u] = low[u] = ++Time ; Q.push(u) ; for(e = List[u] ; e != -1 ; e = edge[e].next){ v = edge[e].v ; if(v == father && flag){ //重边 flag = 0 ; continue ; } if(!dfsn[v]){ tarjan(v , u) ; low[u] = min(low[u] , low[v]) ; } else low[u] = min(low[u] ,dfsn[v]) ; } if(dfsn[u] == low[u]){ color++ ; do{ v = Q.top() ; Q.pop() ; belong[v] = color ; sum[color] += val[v] ; }while(u != v) ; } } int N , M ; void Init(){ id = color = sumall = Time = 0 ; memset(sum , 0 ,sizeof(sum)) ; memset(dfsn , 0 , sizeof(dfsn)) ; memset(List , -1 , sizeof(List)) ; memset(List2 , -1 , sizeof(List2)) ; memset(dp , 0 , sizeof(dp)) ; } int ans ; void dfs(int u , int father){ dp[u] = sum[u] ; int e , v ; for(e = List2[u] ; e != -1 ; e = edge[e].next){ v = edge[e].v ; if(v == father) continue ; dfs(v , u) ; dp[u] += dp[v] ; ans = min(ans , abs(sumall - 2 * dp[v])) ; } } int main(){ int i , u , v , e ; while(cin>>N>>M){ Init() ; for(i = 1 ; i <= N ; i++){ scanf("%d" ,&val[i]) ; sumall += val[i] ; } for(i = 1 ; i <= M ; i++){ scanf("%d%d" ,&u ,&v) ; u++ , v++ ; add_edge(u , v) ; add_edge(v , u) ; } for(i = 1 ; i <= N ; i++){ if(!dfsn[i]) tarjan(i , -1) ; } if(color == 1){ puts("impossible") ; continue ; } for(i = 1 ; i <= N ; i++){ for(e = List[i] ; e != -1 ; e = edge[e].next){ u = edge[e].u ; v = edge[e].v ; if(belong[u] != belong[v]) add_edge2(belong[u] , belong[v]) ; } } ans = 1<<30 ; dfs(1 , -1) ; cout<<ans<<endl ; } return 0 ; }