2015 ACM/ICPC Asia Regional Changchun Online
题意:n个池塘,删掉度数小于2的池塘,输出池塘数为奇数的连通块的池塘容量之和.
思路:两个dfs模拟就行了
1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque> 7 #include <vector> 8 #include <queue> 9 #include <string> 10 #include <cstring> 11 #include <map> 12 #include <stack> 13 #include <set> 14 #define LL long long 15 #define eps 1e-8 16 #define INF 0x3f3f3f3f 17 #define MAXN 10005 18 using namespace std; 19 vector<int> G[MAXN]; 20 int father[MAXN], cnt[MAXN], du[MAXN]; 21 LL v[MAXN]; 22 bool rm[MAXN], vis[MAXN]; 23 struct Node{ 24 int pos, du; 25 Node(int pos = 0, int du = 0) :pos(pos), du(du){}; 26 }; 27 bool compare(Node x, Node y){ 28 return x.du < y.du; 29 } 30 int find(int x){ 31 if (father[x] == x) return x; 32 father[x] = find(father[x]); 33 return father[x]; 34 } 35 void dfs(int x, int p){ 36 vis[x] = true; 37 father[x] = p; 38 for (int i = 0; i < G[x].size(); i++){ 39 int y = G[x][i]; 40 if (rm[y] || vis[y]) continue; 41 dfs(y, p); 42 } 43 } 44 void dfs_rm(int x){ 45 rm[x] = true; 46 for (int i = 0; i < G[x].size(); i++){ 47 du[G[x][i]]--; 48 if (du[G[x][i]] < 2 && !rm[G[x][i]]) dfs_rm(G[x][i]); 49 } 50 } 51 Node node[MAXN]; 52 int main() 53 { 54 //freopen("in.txt", "r", stdin); 55 int T; 56 int m, n; 57 scanf("%d", &T); 58 while (T--){ 59 scanf("%d%d", &n, &m); 60 memset(du, 0, sizeof(du)); 61 for (int i = 1; i <= n; i++){ 62 scanf("%I64d", &v[i]); 63 G[i].clear(); 64 } 65 int x, y; 66 for (int i = 1; i <= m; i++){ 67 scanf("%d%d", &x, &y); 68 du[x]++; 69 du[y]++; 70 G[x].push_back(y); 71 G[y].push_back(x); 72 } 73 memset(rm, 0, sizeof(rm)); 74 //sort(node + 1, node + n + 1, compare); 75 for (int i = 1; i <= n; i++){ 76 //int x = node[i].pos; 77 if (du[i] > 1 || rm[i]) continue; 78 dfs_rm(i); 79 } 80 int p = 1; 81 memset(father, 0, sizeof(father)); 82 memset(vis, 0, sizeof(vis)); 83 for (int i = 1; i <= n; i++){ 84 if (rm[i] || vis[i]) continue; 85 dfs(i, p); 86 p++; 87 } 88 memset(cnt, 0, sizeof(cnt)); 89 for (int i = 1; i <= n; i++){ 90 if (rm[i]) continue; 91 //int x = find(i); 92 cnt[father[i]]++; 93 } 94 LL ans = 0; 95 for (int i = 1; i <= n; i++){ 96 if (cnt[father[i]] & 1){ 97 ans += v[i]; 98 } 99 } 100 printf("%I64d ", ans); 101 } 102 }