标签:mit cstring log min += field ring water sub
题目链接:https://vjudge.net/problem/HDU-4009
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 5612 Accepted Submission(s): 1997
代码一:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 typedef long long LL; 8 const double EPS = 1e-6; 9 const int INF = 2e9; 10 const LL LNF = 9e18; 11 const int MOD = 1e9+7; 12 const int MAXM = 1e6+10; 13 const int MAXN = 1e3+10; 14 15 struct Edge 16 { 17 int u, v, w; 18 }edge[MAXM]; 19 20 int x[MAXN], y[MAXN], z[MAXN]; 21 int pre[MAXN], id[MAXN], vis[MAXN], in[MAXN]; 22 23 LL zhuliu(int root, int n, int m) 24 { 25 LL res = 0; 26 while(true) 27 { 28 for(int i = 0; i<n; i++) 29 in[i] = INF; 30 for(int i = 0; i<m; i++) 31 if(edge[i].u!=edge[i].v && edge[i].w<in[edge[i].v]) 32 { 33 pre[edge[i].v] = edge[i].u; 34 in[edge[i].v] = edge[i].w; 35 } 36 37 for(int i = 0; i<n; i++) 38 if(i!=root && in[i]==INF) 39 return -1; 40 41 int tn = 0; 42 memset(id, -1, sizeof(id)); 43 memset(vis, -1, sizeof(vis)); 44 in[root] = 0; 45 for(int i = 0; i<n; i++) 46 { 47 res += in[i]; 48 int v = i; 49 while(vis[v]!=i && id[v]==-1 && v!=root) 50 { 51 vis[v] = i; 52 v = pre[v]; 53 } 54 if(v!=root && id[v]==-1) 55 { 56 for(int u = pre[v]; u!=v; u = pre[u]) 57 id[u] = tn; 58 id[v] = tn++; 59 } 60 } 61 if(tn==0) break; 62 for(int i = 0; i<n; i++) 63 if(id[i]==-1) 64 id[i] = tn++; 65 66 for(int i = 0; i<m; ) 67 { 68 int v = edge[i].v; 69 edge[i].u = id[edge[i].u]; 70 edge[i].v = id[edge[i].v]; 71 if(edge[i].u!=edge[i].v) 72 edge[i++].w -= in[v]; 73 else 74 swap(edge[i], edge[--m]); 75 } 76 n = tn; 77 root = id[root]; 78 } 79 return res; 80 } 81 82 int main() 83 { 84 int n, m, X, Y, Z; 85 while(scanf("%d%d%d%d", &n, &X, &Y, &Z)!=EOF) 86 { 87 if(!n && !X && !Y && !Z) break; 88 89 for(int i = 0; i<n; i++) 90 scanf("%d%d%d", &x[i], &y[i], &z[i]); 91 92 m = 0; 93 for(int i = 0; i<n; i++) 94 { 95 int num, v; 96 scanf("%d", &num); 97 while(num--) 98 { 99 scanf("%d", &v); v--; 100 edge[m].u = i; 101 edge[m].v = v; 102 edge[m].w = Y*(abs(x[i]-x[v])+abs(y[i]-y[v])+abs(z[i]-z[v])); 103 if(z[i]<z[v]) edge[m].w += Z; 104 m++; 105 } 106 107 edge[m].u = n; 108 edge[m].v = i; 109 edge[m++].w = z[i]*X; 110 } 111 112 LL ans = zhuliu(n, n+1, m); 113 printf("%I64d\n", ans); 114 } 115 }
代码二:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 typedef long long LL; 8 const double EPS = 1e-6; 9 const int INF = 2e9; 10 const LL LNF = 9e18; 11 const int MOD = 1e9+7; 12 const int MAXM = 1e6+10; 13 const int MAXN = 1e3+10; 14 15 struct Edge 16 { 17 int u, v, w; 18 }edge[MAXM]; 19 20 int x[MAXN], y[MAXN], z[MAXN]; 21 int pre[MAXN], id[MAXN], vis[MAXN], in[MAXN]; 22 23 LL zhuliu(int root, int n, int m) 24 { 25 LL res = 0; 26 while(true) 27 { 28 for(int i = 0; i<n; i++) 29 in[i] = INF; 30 for(int i = 0; i<m; i++) 31 if(edge[i].u!=edge[i].v && edge[i].w<in[edge[i].v]) 32 { 33 pre[edge[i].v] = edge[i].u; 34 in[edge[i].v] = edge[i].w; 35 } 36 37 for(int i = 0; i<n; i++) 38 if(i!=root && in[i]==INF) 39 return -1; 40 41 int tn = 0; 42 memset(id, -1, sizeof(id)); 43 memset(vis, -1, sizeof(vis)); 44 in[root] = 0; 45 for(int i = 0; i<n; i++) 46 { 47 res += in[i]; 48 int v = i; 49 while(vis[v]!=i && id[v]==-1 && v!=root) 50 { 51 vis[v] = i; 52 v = pre[v]; 53 } 54 if(v!=root && id[v]==-1) 55 { 56 for(int u = pre[v]; u!=v; u = pre[u]) 57 id[u] = tn; 58 id[v] = tn++; 59 } 60 } 61 if(tn==0) break; 62 for(int i = 0; i<n; i++) 63 if(id[i]==-1) 64 id[i] = tn++; 65 66 for(int i = 0; i<m; i++) 67 { 68 int v = edge[i].v; 69 edge[i].u = id[edge[i].u]; 70 edge[i].v = id[edge[i].v]; 71 if(edge[i].u!=edge[i].v) 72 edge[i].w -= in[v]; 73 } 74 n = tn; 75 root = id[root]; 76 } 77 return res; 78 } 79 80 int main() 81 { 82 int n, m, X, Y, Z; 83 while(scanf("%d%d%d%d", &n, &X, &Y, &Z)!=EOF) 84 { 85 if(!n && !X && !Y && !Z) break; 86 87 for(int i = 0; i<n; i++) 88 scanf("%d%d%d", &x[i], &y[i], &z[i]); 89 90 m = 0; 91 for(int i = 0; i<n; i++) 92 { 93 int num, v; 94 scanf("%d", &num); 95 while(num--) 96 { 97 scanf("%d", &v); v--; 98 edge[m].u = i; 99 edge[m].v = v; 100 edge[m].w = Y*(abs(x[i]-x[v])+abs(y[i]-y[v])+abs(z[i]-z[v])); 101 if(z[i]<z[v]) edge[m].w += Z; 102 m++; 103 } 104 105 edge[m].u = n; 106 edge[m].v = i; 107 edge[m++].w = z[i]*X; 108 } 109 110 LL ans = zhuliu(n, n+1, m); 111 printf("%I64d\n", ans); 112 } 113 }
HDU4009 Transfer water —— 最小树形图 + 超级点
标签:mit cstring log min += field ring water sub
原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7768030.html