remove的过程就像是拓扑排序,而最后统计sum可以用并查集,每个集合维护集合的size、sum。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <queue> 6 using namespace std; 7 8 typedef long long ll; 9 const int INF = 999999999; 10 const int N = 20000; 11 const int M = 200000; 12 int f[N]; 13 int sz[N]; 14 ll sum[N]; 15 int in[N]; 16 int head[N]; 17 queue<int> q; 18 int n, m, e; 19 20 struct Edge 21 { 22 int v, next; 23 } edge[M << 1]; 24 25 void addEdge( int u, int v ) 26 { 27 edge[e].v = v; 28 edge[e].next = head[u]; 29 head[u] = e++; 30 } 31 32 void init() 33 { 34 while ( !q.empty() ) q.pop(); 35 e = 0; 36 memset( in, 0, sizeof(in) ); 37 memset( head, -1, sizeof(head) ); 38 for ( int i = 1; i <= n; i++ ) 39 { 40 f[i] = i; 41 sz[i] = 1; 42 } 43 } 44 45 int findf( int x ) 46 { 47 if ( f[x] != x ) f[x] = findf( f[x] ); 48 return f[x]; 49 } 50 51 void union_set( int x, int y ) 52 { 53 x = findf(x), y = findf(y); 54 if ( x != y ) 55 { 56 f[x] = y; 57 sz[y] += sz[x]; 58 sum[y] += sum[x]; 59 } 60 } 61 62 int main () 63 { 64 int t; 65 scanf("%d", &t); 66 while ( t-- ) 67 { 68 scanf("%d%d", &n, &m); 69 init(); 70 for ( int i = 1; i <= n; i++ ) 71 { 72 scanf("%I64d", &sum[i]); 73 } 74 while ( m-- ) 75 { 76 int u, v; 77 scanf("%d%d", &u, &v); 78 in[u]++; 79 in[v]++; 80 addEdge( u, v ); 81 addEdge( v, u ); 82 } 83 for ( int i = 1; i <= n; i++ ) 84 { 85 if ( in[i] < 2 ) 86 { 87 q.push(i); 88 in[i] = INF; 89 } 90 } 91 while ( !q.empty() ) 92 { 93 int u = q.front(); 94 q.pop(); 95 for ( int i = head[u]; i != -1; i = edge[i].next ) 96 { 97 int v = edge[i].v; 98 in[v]--; 99 if ( in[v] < 2 ) 100 { 101 q.push(v); 102 in[v] = INF; 103 } 104 } 105 } 106 for ( int i = 1; i <= n; i++ ) 107 { 108 if ( in[i] > n ) continue; 109 for ( int j = head[i]; j != -1; j = edge[j].next ) 110 { 111 int v = edge[j].v; 112 if ( in[v] > n ) continue; 113 union_set( i, v ); 114 } 115 } 116 ll ans = 0; 117 for ( int i = 1; i <= n; i++ ) 118 { 119 if ( in[i] < n && f[i] == i && sz[i] % 2 == 1 ) 120 { 121 ans += sum[i]; 122 } 123 } 124 printf("%I64d ", ans); 125 } 126 return 0; 127 }