标签:
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1394 Accepted Submission(s): 467
题意:有很多池塘,有的两个池塘间有管道连着。经费问题,要删除一些就连着一个管道的池塘。注意删除一个池塘之后,原本可能不用删除的,可能需要删除。4连着两个池塘2和3,2被删除后,4也要删除,因为连着4的管道由之前的2变成1个了。问剩下的在一个联通块里边池塘个数是奇数的,池塘价值之和。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<stack> 6 #include<vector> 7 #include<algorithm> 8 9 using namespace std; 10 11 #define maxn 10007 12 13 vector<vector<int> > G; 14 int used[maxn]; 15 int a[maxn*10], b[maxn*10]; 16 int f[maxn], v[maxn], sum[maxn], r[maxn]; 17 long long ans; 18 19 int found(int x) 20 { 21 if(f[x] != x) 22 f[x] = found(f[x]); 23 return f[x]; 24 } 25 26 int main() 27 { 28 int c, n, m; 29 scanf("%d", &c); 30 queue<int> Q; 31 32 while(c--) 33 { 34 ans = 0; 35 G.resize(maxn+2); 36 G.clear(); 37 memset(used, 0, sizeof(used)); 38 memset(sum, 0, sizeof(sum)); 39 memset(a, 0, sizeof(a)); 40 memset(b, 0, sizeof(b)); 41 42 scanf("%d%d", &n, &m); 43 for(int i = 1; i <= n; i++) 44 { 45 f[i] = i; 46 r[i] = 0; 47 scanf("%d", &v[i]); 48 } 49 50 for(int i = 0; i < m; i++) 51 { 52 scanf("%d%d", &a[i], &b[i]); 53 r[a[i]]++, r[b[i]]++; 54 G[a[i]].push_back(b[i]); 55 G[b[i]].push_back(a[i]); 56 } 57 for(int i = 1; i <= n; i++) 58 if(r[i] < 2) 59 Q.push(i); 60 61 while(Q.size()) 62 { 63 int u = Q.front(); 64 Q.pop(); 65 used[u] = 1; 66 int len = G[u].size(); 67 for(int i = 0; i < len; i++) 68 { 69 int v = G[u][i]; 70 r[v]--; 71 if(r[v] < 2 && !used[v]) 72 Q.push(v); 73 } 74 } 75 for(int i = 0; i < m; i++) 76 { 77 if(!used[a[i]] && !used[b[i]]) 78 { 79 int u = found(a[i]); 80 int v = found(b[i]); 81 if(u != v) 82 f[v] = u; 83 } 84 } 85 for(int i = 1; i <= n; i++) 86 if(!used[i]) 87 sum[found(i)]++; 88 89 for(int i = 1; i <= n; i++) 90 { 91 if(!used[i] && sum[f[i]] % 2) 92 ans += v[i]; 93 } 94 printf("%I64d\n", ans); 95 } 96 return 0; 97 }
标签:
原文地址:http://www.cnblogs.com/Tinamei/p/4810881.html