Ponds
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 985 Accepted Submission(s): 328
Now Betty wants to remove some ponds because she does not have enough money. But each time when she removes a pond, she can only remove the ponds which are connected with less than two ponds, or the pond will explode.
Note that Betty should keep removing ponds until no more ponds can be removed. After that, please help her calculate the sum of the value for each connected component consisting of a odd number of ponds
For each test case, the first line contains two number separated by a blank. One is the number p(1≤p≤104) which represents the number of ponds she owns, and the other is the number m(1≤m≤105) which represents the number of pipes.
The next line contains p numbers v1,...,vp, where vi(1≤vi≤108) indicating the value of pond i.
Each of the last m lines contain two numbers a and b, which indicates that pond a and pond b are connected by a pipe.
1
7 7
1 2 3 4 5 6 7
1 4
1 5
4 5
2 3
2 6
3 6
2 7
先说题意吧 :
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int oo = 0x3f3f3f3f; 8 const int N = 100005; 9 typedef long long LL; 10 struct da 11 { 12 int u, v, next; 13 }as[N*4]; 14 int head[N], cnt, n, m, vis[N], in[N]; 15 /**< in记录每个点的度数 vis标记这个点是否处理过 val记录每个池塘的价值 */ 16 LL val[N]; 17 void add(int u, int v) 18 { 19 as[cnt].v = v; 20 as[cnt].next = head[u]; 21 head[u] = cnt++; 22 } 23 void init() 24 { 25 memset(head, -1, sizeof(head)); 26 memset(in, 0, sizeof(in)); 27 cnt = 0; 28 } 29 void dfs(int u)/**< 将度数小于2的点以及这个点能到达的边的度数都减去1 */ 30 { 31 vis[u] = 1;in[u]--; 32 for(int i = head[u]; i != -1; i = as[i].next) 33 { 34 int v = as[i].v; 35 if(vis[v]) continue;/**< 因为是无向图 有1-2 就有2-1 避免通一条边多次处理 */ 36 in[v]--; 37 if(in[v] < 2)/**< 如果这个点的度数小于2 处理这个点的连边*/ 38 dfs(v); 39 } 40 } 41 void dfs1(int u, LL &num, LL &sum)/**< 强连通的池塘的价值和 */ 42 { 43 vis[u] = 1; 44 num++; sum += val[u]; 45 for(int i = head[u]; i != -1; i = as[i].next) 46 { 47 int v = as[i].v; 48 if(vis[v]) continue; 49 if(in[v] < 2) continue; 50 dfs1(v, num, sum); 51 } 52 } 53 LL solve() 54 { 55 int i; 56 memset(vis, 0, sizeof(vis)); 57 for(i = 1; i <= n; i++) 58 { 59 if(vis[i] == 0 && in[i] < 2)/**< 如果这个点没有遍历过 并且度数小于2 对他的连边处理 */ 60 dfs(i); 61 } 62 LL sum=0, ans = 0, QQ = 0; 63 memset(vis, 0, sizeof(vis)); 64 for(i = 1; i <= n; i++) 65 { 66 QQ = 0, sum = 0; 67 if(vis[i] == 0 && in[i] >= 2) 68 { 69 dfs1(i, sum, QQ); 70 if(sum%2)ans += QQ;/**< 找出池塘个数为奇数的和 */ 71 } 72 } 73 return ans; 74 } 75 int main() 76 { 77 int T, i; 78 scanf("%d", &T); 79 while(T--) 80 { 81 init(); 82 scanf("%d %d", &n, &m); 83 for(i = 1; i <= n; i++) 84 scanf("%I64d", &val[i]); 85 while(m--) 86 { 87 int a, b; 88 scanf("%d %d", &a, &b); 89 if(a == b)continue; 90 add(a, b); 91 add(b, a); 92 in[a]++; 93 in[b]++; 94 } 95 LL ans = solve(); 96 printf("%I64d\n", ans); 97 } 98 return 0; 99 }
数据:
8 8
1 1 1 1 1 1 1 1
1 2
2 3
3 4
1 4
5 6
6 7
5 7
7 8
3
——————————————————————————————————————————————————————
7 8
1 2 3 4 5 6 7
1 2
1 3
2 4
2 5
4 5
3 6
3 7
6 7
28
————————————————————————————————————-
3 2
1 1 1
1 2
2 3
0
————————————————————————————----————————————————————
7 7
1 1 1 1 1 1 1
1 2
1 3
1 4
1 5
2 6
2 7
6 7
3
——————————————————————————————————————————————————————————
5 6
1 1 1 1 1
1 2
1 3
1 4
1 5
2 3
4 5
5
7 8
1 1 1 1 1 1 1
1 2
1 5
2 3
2 4
3 4
5 6
5 7
6 7
7