参考博客 点我ヾ(^▽^*)))
// 例题 poj 3164 (定根)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-16 15:17:03 7 * @LastEditTime: 2019-10-16 15:55:18 8 */ 9 #include<cstdio> 10 #include<cmath> 11 #include<cstring> 12 #include<algorithm> 13 using namespace std; 14 const int INF = 0x3f3f3f3f; 15 const int MAXN = 1000+5; 16 const int MAXM = MAXN*MAXN; 17 18 struct node { 19 int from, to; 20 double cost; 21 } edge[MAXM]; 22 23 int n, m;// n个点 m条有向边 24 int pre[MAXN];// 储存父节点 25 int vis[MAXN];// 标记作用 26 int id[MAXN];// id[i]记录节点i所在环的编号 27 double in[MAXN];// in[i]记录i入边最小的权值 28 29 double zhuliu(int root) { 30 double res = 0; 31 while(1) { 32 for(int i = 0; i != n; ++i) in[i] = INF; 33 for(int i = 0; i != m; ++i) { 34 node e = edge[i]; 35 if(e.from != e.to && e.cost < in[e.to]) { 36 pre[e.to] = e.from; 37 in[e.to] = e.cost; 38 } 39 } 40 for(int i = 0; i != n; ++i) 41 if(i != root && in[i] == INF) 42 return -1; 43 int tn = 0; 44 memset(id, -1, sizeof(id)); 45 memset(vis, -1, sizeof(vis)); 46 in[root] = 0; 47 for(int i = 0; i != n; ++i) { 48 res += in[i]; 49 int v = i; 50 while(vis[v] != i && id[v] == -1 && v != root) { 51 vis[v] = i; 52 v = pre[v]; 53 } 54 if(v != root && id[v] == -1) { 55 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn; 56 id[v] = tn++; 57 } 58 } 59 if(tn == 0) break; 60 for(int i = 0; i != n; ++i) { 61 if(id[i] == -1) id[i] = tn++; 62 } 63 for(int i = 0; i != m; ++i) { 64 int v = edge[i].to; 65 edge[i].from = id[edge[i].from]; 66 edge[i].to = id[edge[i].to]; 67 if(edge[i].from != edge[i].to) edge[i].cost -= in[v]; 68 } 69 n = tn; 70 root = id[root]; 71 } 72 return res; 73 } 74 75 int main() { 76 while(scanf("%d%d", &n, &m) == 2) { 77 double x[MAXN], y[MAXN]; 78 for(int i = 0; i != n; ++i) scanf("%lf%lf", &x[i], &y[i]); 79 int s, e; 80 for(int i = 0; i != m; ++i) { 81 scanf("%d%d", &s, &e); 82 --s; --e; 83 edge[i].from = s; 84 edge[i].to = e; 85 edge[i].cost = sqrt((x[s]-x[e])*(x[s]-x[e])+(y[s]-y[e])*(y[s]-y[e])); 86 } 87 double ans = zhuliu(0); 88 if(ans == -1) printf("poor snoopy "); 89 else printf("%.2lf ", ans); 90 } 91 return 0; 92 }
// hdu 2121 (不定跟)
思路: 虚拟源点
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-18 19:02:26 7 * @LastEditTime: 2019-10-19 01:13:33 8 */ 9 #include<cstdio> 10 #include<cstring> 11 #include<cmath> 12 #include<iostream> 13 #include<string> 14 #include<algorithm> 15 #include<vector> 16 #include<queue> 17 #include<stack> 18 #include<set> 19 #include<map> 20 #define rep(i, n) for(int i=0;i!=n;++i) 21 #define per(i, n) for(int i=n-1;i>=0;--i) 22 #define Rep(i, sta, n) for(int i=sta;i!=n;++i) 23 #define rep1(i, n) for(int i=1;i<=n;++i) 24 #define per1(i, n) for(int i=n;i>=1;--i) 25 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i) 26 #define L k<<1 27 #define R k<<1|1 28 #define mid (tree[k].l+tree[k].r)>>1 29 using namespace std; 30 const int INF = 0x3f3f3f3f; 31 typedef long long ll; 32 const int MAXN = 1000+5; 33 const int MAXM = 10000+5; 34 35 struct node { 36 int from, to, w; 37 } edge[MAXM+MAXN]; 38 39 int pos; 40 int pre[MAXN], vis[MAXN], id[MAXN], in[MAXN]; 41 42 ll zhuliu(int n, int m) { 43 int root = 0; 44 ll ans = 0; 45 while(1) { 46 rep(i, n) in[i] = INF; 47 rep(i, m) { 48 int u = edge[i].from, v = edge[i].to; 49 if(u != v && edge[i].w < in[v]) { 50 pre[v] = u; 51 in[v] = edge[i].w; 52 if(u == root) pos = i; 53 } 54 } 55 rep(i, n) { 56 if(i != root && in[i] == INF) return -1; 57 } 58 int tn = 0; 59 in[root] = 0; 60 rep(i, n) id[i] = vis[i] = -1; 61 rep(i, n) { 62 ans += in[i]; 63 int v = i; 64 while(vis[v] != i && id[v] == -1 && v != root) { 65 vis[v] = i; 66 v = pre[v]; 67 } 68 if(v != root && id[v] == -1) { 69 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn; 70 id[v] = tn++; 71 } 72 } 73 if(tn == 0) break; 74 rep(i, n) if(id[i] == -1) id[i] = tn++; 75 rep(i, m) { 76 int v = edge[i].to; 77 edge[i].from = id[edge[i].from]; 78 edge[i].to = id[edge[i].to]; 79 if(edge[i].from != edge[i].to) edge[i].w -= in[v]; 80 } 81 root = id[root]; 82 n = tn; 83 } 84 return ans; 85 } 86 87 int main() { 88 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 89 int n, m, sum; 90 while(cin >> n >> m) { 91 int s, e; 92 sum = 0; 93 rep(i, m) { 94 cin >> edge[i].from >> edge[i].to >> edge[i].w; 95 ++edge[i].from; ++edge[i].to; 96 sum += edge[i].w; 97 } 98 ++sum; 99 Rep(i, m, n+m) { 100 edge[i].from = 0; edge[i].to = i - m + 1; 101 edge[i].w = sum; 102 } 103 ll ans = zhuliu(n+1, n+m); 104 if(ans == -1 || ans-sum >= sum) cout << "impossible" << " "; 105 else cout << ans-sum << " " << pos-m << " "; 106 } 107 return 0; 108 }
// hdu 4009 (生成森林)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-19 16:21:30 7 * @LastEditTime: 2019-10-19 17:28:08 8 */ 9 #include<cstdio> 10 #include<cstring> 11 #include<cmath> 12 #include<iostream> 13 #include<string> 14 #include<algorithm> 15 #include<vector> 16 #include<queue> 17 #include<stack> 18 #include<set> 19 #include<map> 20 #define rep(i, n) for(int i=0;i!=n;++i) 21 #define per(i, n) for(int i=n-1;i>=0;--i) 22 #define Rep(i, sta, n) for(int i=sta;i!=n;++i) 23 #define rep1(i, n) for(int i=1;i<=n;++i) 24 #define per1(i, n) for(int i=n;i>=1;--i) 25 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i) 26 #define L k<<1 27 #define R k<<1|1 28 #define mid (tree[k].l+tree[k].r)>>1 29 using namespace std; 30 const int INF = 0x3f3f3f3f; 31 typedef long long ll; 32 const int MAXN = 1000+5; 33 const int MAXM = MAXN*MAXN+MAXN; 34 35 struct node { 36 int from, to, w; 37 } edge[MAXM]; 38 39 int X, Y, Z; 40 int x[MAXN], y[MAXN], z[MAXN]; 41 42 int pre[MAXN], vis[MAXN], id[MAXN], in[MAXN]; 43 44 int zhuliu(int n, int m) { 45 int root = 0; 46 int sum = 0; 47 while(1) { 48 rep(i, n) in[i] = INF; 49 rep(i, m) { 50 int u = edge[i].from, v = edge[i].to; 51 if(u != v && edge[i].w < in[v]) { 52 pre[v] = u; 53 in[v] = edge[i].w; 54 } 55 } 56 rep(i, n) if(i != root && in[i] == INF) return -1; 57 int tn = 0; 58 in[root] = 0; 59 rep(i, n) vis[i] = id[i] = -1; 60 rep(i, n) { 61 sum += in[i]; 62 int v = i; 63 while(vis[v] != i && id[v] == -1 && v != root) { 64 vis[v] = i; 65 v = pre[v]; 66 } 67 if(v != root && id[v] == -1) { 68 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn; 69 id[v] = tn++; 70 } 71 } 72 if(tn == 0) break; 73 rep(i, n) if(id[i] == -1) id[i] = tn++; 74 rep(i, m) { 75 int v = edge[i].to; 76 edge[i].from = id[edge[i].from]; 77 edge[i].to = id[edge[i].to]; 78 if(edge[i].from != edge[i].to) edge[i].w -= in[v]; 79 } 80 root = id[root]; 81 n = tn; 82 } 83 return sum; 84 } 85 86 int main() { 87 //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 88 int n, m; 89 while(scanf("%d%d%d%d", &n, &X, &Y, &Z) == 4 && n) { //cin >> n >> X >> Y >> Z 90 m = 0; 91 rep1(i, n) scanf("%d%d%d", &x[i], &y[i], &z[i]); //cin >> x[i] >> y[i] >> z[i]; 92 int c, v, sum; 93 rep1(u, n) { 94 scanf("%d", &c); //cin >> c; 95 rep(j, c) { 96 scanf("%d", &v); //cin >> v; 97 if(u != v) { 98 sum = (abs(x[u]-x[v])+abs(y[u]-y[v])+abs(z[u]-z[v]))*Y; 99 if(z[v] > z[u]) sum += Z; 100 edge[m].from = u; edge[m].to = v; 101 edge[m].w = sum; 102 ++m; 103 } 104 } 105 } 106 Rep(i, m, m+n) { 107 edge[i].from = 0; edge[i].to = i - m + 1; 108 edge[i].w = z[i-m+1]*X; 109 } 110 int ans = zhuliu(n+1, n+m); 111 printf("%d ", ans); //cout << ans << " "; 112 } 113 return 0; 114 }