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
本文介绍了一种算法,用于计算在特定条件下剩余池塘的价值总和。该算法首先去除度数小于2的节点,然后计算剩余强连通组件中奇数个节点的价值总和。
616

被折叠的 条评论
为什么被折叠?



