[kuangbin带你飞]之'生成树'专题
带飞网址: https://vjudge.net/article/187
专题八 生成树
√ POJ 1679 The Unique MST
√ HDU 4081 Qin Shi Huang's National Road System
√ UVA 10600 ACM Contest and Blackout
√ UVA 10462 Is There A Second Way Left?
√ POJ 3164 Command Network
√ UVA 11183 Teen Girl Squad
√ HDU 2121 Ice_cream’s world II
√ HDU 4009 Transfer water
√ UVA 10766 Organising the Organisation
SPOJ DETER3 Find The Determinant III
URAL 1627 Join
√ HDU 4305 Lightning
HDU 4408 Minimum Spanning Tree
SPOJ HIGH Highways
// poj 1679
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 struct Edge { 7 int s, e; 8 int w; 9 int flag; 10 int used; 11 int del; 12 }edges[10005]; 13 14 bool first; 15 int n, m, cnt; 16 17 bool cmp(const Edge& a, const Edge& b) { 18 return a.w < b.w; 19 } 20 21 int p[1005]; 22 int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); } 23 24 int kruskal() { 25 int ans = 0; 26 cnt = 1; 27 for(int i = 0; i != n; ++i) p[i] = i; 28 for(int i = 0; i != m; ++i) { 29 if(edges[i].del) continue; 30 int x = find(edges[i].s); 31 int y = find(edges[i].e); 32 if(x != y) { 33 ans += edges[i].w; 34 p[x] = y; 35 cnt++; 36 if(first) edges[i].used = 1; 37 } 38 if(cnt == n) break; 39 } 40 return ans; 41 } 42 43 int main() { 44 int T; 45 scanf("%d", &T); 46 while(T--) { 47 scanf("%d%d", &n, &m); 48 if(m == 0) { 49 printf("0\n"); 50 continue; 51 } 52 int x, y; 53 for(int i = 0; i != m; ++i) { 54 scanf("%d%d%d", &edges[i].s, &edges[i].e, &edges[i].w); 55 edges[i].flag = edges[i].del = edges[i].used = 0; 56 edges[i].s--; 57 edges[i].e--; 58 } 59 sort(edges, edges+m, cmp); 60 for(int i = 1; i <= m-1; ++i) if(edges[i].w == edges[i-1].w) edges[i].flag = edges[i-1].flag = 1; 61 // int ans = 0; 62 // for(int i = 0; i != m; ++i) { 63 // if(edges[i].flag) ans++; 64 // } 65 // printf("%d\n", ans); 66 first = true; 67 int ans1 = kruskal(); 68 first = false; 69 if(cnt != n) { 70 printf("Not Unique!\n"); 71 continue; 72 } 73 //printf("%d\n", ans1); 74 bool have = false; 75 for(int i = 0; i != m; ++i) { 76 if(edges[i].used && edges[i].flag) { 77 have = true; 78 break; 79 } 80 } 81 if(!have) { 82 printf("%d\n", ans1); 83 continue; 84 } 85 bool unique_ = true; 86 for(int i = 0; i != m; ++i) { 87 if(edges[i].used && edges[i].flag) { 88 edges[i].del = 1; 89 int ans2 = kruskal(); 90 if(ans1 == ans2 && cnt == n) { 91 unique_ = false; 92 break; 93 } 94 edges[i].del = 0; 95 } 96 } 97 if(!unique_) printf("Not Unique!\n"); 98 else printf("%d\n", ans1); 99 } 100 return 0; 101 }
// hdu 4081
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-15 17:48:20 7 * @LastEditTime: 2019-10-16 00:22:22 8 */ 9 #include<cstdio> 10 #include<iostream> 11 #include<cmath> 12 #include<algorithm> 13 using namespace std; 14 const int MAXN = 1000+5; 15 const int INF = 2147483647; 16 17 int n; 18 double x[MAXN], y[MAXN]; 19 double G[MAXN][MAXN]; 20 int peo[MAXN]; 21 22 int vis[MAXN], pre[MAXN], used[MAXN][MAXN]; 23 double path[MAXN][MAXN]; 24 double dis[MAXN]; 25 26 inline double prim() { 27 double sum = 0; 28 for(int i = 0; i != n; ++i) { 29 dis[i] = G[i][0]; 30 vis[i] = pre[i] = 0; 31 for(int j = 0; j != n; ++j) used[i][j] = path[i][j] = 0; 32 } 33 vis[0] = 1; 34 for(int i = 0; i != n-1; ++i) { 35 double minn = INF; 36 int t; 37 for(int j = 0; j != n; ++j) { 38 if(!vis[j] && dis[j] < minn) { 39 minn = dis[j]; 40 t = j; 41 } 42 } 43 vis[t] = 1; 44 used[t][pre[t]] = used[pre[t]][t] = 1; 45 sum += minn; 46 for(int j = 0; j != n; ++j) { 47 if(!vis[j] && dis[j] > G[t][j]) { 48 dis[j] = G[t][j]; 49 pre[j] = t; 50 } 51 if(vis[j] && j != t) { 52 path[j][t] = path[t][j] = max(path[j][pre[t]], minn); 53 } 54 } 55 } 56 return sum; 57 } 58 59 int main() { 60 int T; 61 scanf("%d", &T); 62 while(T--) { 63 scanf("%d", &n); 64 for(int i = 0; i != n; ++i) { 65 scanf("%lf%lf%d", &x[i], &y[i], &peo[i]); 66 for(int j = i-1; j >= 0; --j) { 67 G[i][j] = G[j][i] = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 68 } 69 G[i][i] = INF; 70 } 71 double sum = prim(); 72 double m = 0; 73 for(int i = 0; i != n; ++i) { 74 for(int j = 0; j != n; ++j) if(i != j) { 75 if(used[i][j]) { 76 m = max(m, (peo[i]+peo[j])*1.0/(sum-G[i][j])); 77 } 78 else m = max(m, (peo[i]+peo[j])*1.0/(sum-path[i][j])); 79 } 80 } 81 printf("%.2lf\n", m); 82 } 83 return 0; 84 }
// UVA 10600
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-21 22:54:50 7 * @LastEditTime: 2019-10-21 23:21:57 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 33 inline int read() { 34 char c=getchar();int x=0,f=1; 35 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 36 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 37 return x*f; 38 } 39 // ----------------------------------------------------- 40 const int MAXN = 100+5; 41 42 int n, m; 43 int G[MAXN][MAXN]; 44 int vis[MAXN], dis[MAXN], pre[MAXN], used[MAXN][MAXN], path[MAXN][MAXN]; 45 46 inline int prim() { 47 int ans = 0; 48 rep1(i, n) { 49 dis[i] = G[i][1]; 50 pre[i] = 1; vis[i] = 0; 51 rep1(j, n) used[i][j] = path[i][j] = 0; 52 } 53 vis[1] = 1; 54 rep(i, n-1) { 55 int minn = INF; 56 int t; 57 rep1(j, n) { 58 if(!vis[j] && dis[j] < minn) { 59 minn = dis[j]; 60 t = j; 61 } 62 } 63 vis[t] = 1; 64 ans += minn; 65 used[t][pre[t]] = used[pre[t]][t] = 1; 66 rep1(j, n) { 67 if(!vis[j] && dis[j] > G[t][j]) { 68 pre[j] = t; 69 dis[j] = G[t][j]; 70 } 71 if(vis[j] && j != t) { 72 path[j][t] = path[t][j] = max(path[j][pre[t]], minn); 73 } 74 } 75 } 76 return ans; 77 } 78 79 int main() { 80 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 81 int T = read(); 82 while(T--) { 83 n = read(); m = read(); 84 rep1(i, n) rep1(j, n) G[i][j] = INF; 85 int s, e, v; 86 rep(i, m) { 87 s = read(); e = read(); v = read(); 88 G[s][e] = G[e][s] = v; 89 } 90 int sum = prim(); 91 int ans = INF; 92 rep1(i, n) Rep1(j, i+1, n) { 93 if(G[i][j] != INF && !used[i][j]) { 94 ans = min(ans, sum-path[i][j]+G[i][j]); 95 } 96 } 97 cout << sum << " " << ans << "\n"; 98 } 99 return 0; 100 }
// UVA 10462
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-21 23:48:51 7 * @LastEditTime: 2019-10-22 00:41:56 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 33 inline int read() { 34 char c=getchar();int x=0,f=1; 35 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 36 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 37 return x*f; 38 } 39 // ----------------------------------------------------- 40 const int MAXN = 100+5; 41 const int MAXM = 200+5; 42 43 struct node { 44 int s, e, w; 45 int used, del; 46 bool operator < (const node &a) const { 47 return w < a.w; 48 } 49 } edge[MAXM]; 50 51 int n, m; 52 int fa[MAXN]; 53 bool First; 54 55 inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } 56 57 inline int krustra() { 58 int sum = 0; 59 int cnt = 1; 60 rep1(i, n) fa[i] = i; 61 rep(i, m) { 62 if(cnt == n) break; 63 if(edge[i].del) continue; 64 int xf = find(edge[i].s); 65 int yf = find(edge[i].e); 66 if(xf != yf) { 67 fa[xf] = yf; 68 sum += edge[i].w; 69 ++cnt; 70 if(First) edge[i].used = 1; 71 } 72 } 73 if(cnt != n) return -1; 74 return sum; 75 } 76 77 int main() { 78 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 79 int T = read(); 80 int cnt = 1; 81 while(T--) { 82 n = read(); m = read(); 83 int s, e, v; 84 rep(i, m) { 85 edge[i].s = read(); 86 edge[i].e = read(); 87 edge[i].w = read(); 88 edge[i].used = edge[i].del = 0; 89 } 90 cout << "Case #" << cnt++ << " : "; 91 sort(edge, edge+m); 92 First = true; 93 int sum = krustra(); 94 First = false; 95 if(sum == -1) cout << "No way\n"; 96 else { 97 int ans = INF; 98 rep(i, m) { 99 if(edge[i].used) { 100 edge[i].del = 1; 101 int t = krustra(); 102 edge[i].del = 0; 103 if(t != -1) ans = min(ans, t); 104 } 105 } 106 if(ans == INF) cout << "No second way\n"; 107 else cout << ans << "\n"; 108 } 109 } 110 return 0; 111 }
// poj 3164
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\n"); 89 else printf("%.2lf\n", ans); 90 } 91 return 0; 92 }
// UVA 11183
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-22 22:47:44 7 * @LastEditTime: 2019-10-22 23:23:50 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 33 inline int read() { 34 char c=getchar();int x=0,f=1; 35 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 36 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 37 return x*f; 38 } 39 // ----------------------------------------------------- 40 const int MAXN = 1000+5; 41 const int MAXM = 40000+5; 42 43 struct node { 44 int from, to, w; 45 } edge[MAXM]; 46 47 int n, m; 48 int pre[MAXN], in[MAXN], vis[MAXN], id[MAXN]; 49 50 inline int zhuliu() { 51 int sum = 0; 52 int root = 0; 53 while(1) { 54 rep(i, n) in[i] = INF; 55 rep(i, m) { 56 int u = edge[i].from, v = edge[i].to; 57 if(u != v && edge[i].w < in[v]) { 58 in[v] = edge[i].w; 59 pre[v] = u; 60 } 61 } 62 rep(i, n) if(i != root && in[i] == INF) return -1; 63 int tn = 0; 64 in[root] = 0; 65 rep(i, n) vis[i] = id[i] = -1; 66 rep(i, n) { 67 sum += in[i]; 68 int v = i; 69 while(vis[v] != i && id[v] == -1 && v != root) { 70 vis[v] = i; 71 v = pre[v]; 72 } 73 if(v != root && id[v] == -1) { 74 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn; 75 id[v] = tn++; 76 } 77 } 78 if(!tn) break; 79 rep(i, n) if(id[i] == -1) id[i] = tn++; 80 rep(i, m) { 81 int v = edge[i].to; 82 edge[i].from = id[edge[i].from]; 83 edge[i].to = id[edge[i].to]; 84 if(edge[i].from != edge[i].to) edge[i].w -= in[v]; 85 } 86 root = id[root]; 87 n = tn; 88 } 89 return sum; 90 } 91 92 int main() { 93 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 94 int T = read(); 95 int cnt = 1; 96 while(T--) { 97 n = read(), m = read(); 98 rep(i, m) { 99 edge[i].from = read(); 100 edge[i].to = read(); 101 edge[i].w = read(); 102 } 103 int ans = zhuliu(); 104 cout << "Case #" << cnt++ << ": "; 105 if(ans == -1) cout << "Possums!" << "\n"; 106 else cout << ans << "\n"; 107 } 108 return 0; 109 }
// hdu 2121
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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" << "\n\n"; 105 else cout << ans-sum << " " << pos-m << "\n\n"; 106 } 107 return 0; 108 }
// hdu 4009
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\n", ans); //cout << ans << "\n"; 112 } 113 return 0; 114 }
// UVA 10766
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-24 00:47:06 7 * @LastEditTime: 2019-10-24 20:22:52 8 */ 9 #include<cstdio> 10 #include<cmath> 11 #include<algorithm> 12 using namespace std; 13 typedef long long ll; 14 const int MAXN = 50+5; 15 16 ll matrix_tree(ll c[][MAXN], int n) { 17 ll ans = 1; 18 for(int i = 1; i <= n; ++i) { 19 for(int j = i+1; j <= n; ++j) { 20 while(c[j][i]) { 21 ll t = c[i][i]/c[j][i]; 22 for(int k = i; k <= n; ++k) c[i][k] -= c[j][k]*t; 23 swap(c[i], c[j]); 24 ans = -ans; 25 } 26 } 27 if(!c[i][i]) return 0; 28 ans *= c[i][i]; 29 } 30 return ans>0?ans:-ans; 31 } 32 33 int main() { 34 int n, m, k; 35 ll mat[MAXN][MAXN], G[MAXN][MAXN]; 36 while(scanf("%d%d%d", &n, &m, &k) == 3) { 37 for(int i = 1; i <= n; ++i) { 38 for(int j = 1; j <= n; ++j) { 39 G[i][j] = 1; mat[i][j] = 0; 40 } 41 } 42 int x, y; 43 for(int i = 0; i != m; ++i) { 44 scanf("%d%d", &x, &y); 45 G[x][y] = G[y][x] = 0; 46 } 47 for(int i = 1; i <= n; ++i) { 48 for(int j = i+1; j <= n; ++j) { 49 if(i != j && G[i][j]) { 50 ++mat[i][i]; ++mat[j][j]; 51 mat[i][j] = mat[j][i] = -1; 52 } 53 } 54 } 55 printf("%lld\n", matrix_tree(mat, n-1)); 56 } 57 return 0; 58 }
// hdu 4305
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-20 14:10:38 7 * @LastEditTime: 2019-10-21 16:25:00 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 33 inline int read() { 34 char c=getchar();int x=0,f=1; 35 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 36 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 37 return x*f; 38 } 39 40 const int MAXN = 300+5; 41 const int mod = 10007; 42 43 struct node { 44 int x, y; 45 } p[MAXN]; 46 47 int inv[mod];// inv[i]表示i在%mod下的逆元 48 void init() {// 求逆元(mod质素 才能用递推--素数筛选) 49 inv[1] = 1; 50 Rep(i, 2, mod) inv[i] = (mod-mod/i)*inv[mod%i]%mod; 51 } 52 53 inline int det(int c[][MAXN], int n) {// 高斯消元求上三角矩阵 54 int i, j, k, ans = 1; 55 for(i = 0; i != n; ++i) { 56 for(j = 0; j != n; ++j) { 57 c[i][j] = (c[i][j]%mod+mod)%mod; 58 } 59 } 60 for(i = 0; i != n; ++i) { 61 for(j = i; j != n; ++j) if(c[i][j]) break;// 找出第i行起第i列不为0的行 62 if(i != j) swap(c[i], c[j]); 63 ans = ans*c[i][i]%mod; 64 for(j = i+1; j != n; ++j) {// 第j行第i列变为0 65 int d = c[j][i]*inv[c[i][i]]%mod;// c[j][i]-d*c[i][i] = 0 66 for(k = i; k != n; ++k) {// (c[j][i]->0同时其它c[j][k]减去d*c[i][k], k=i+1 也行,因为k=i没必要) 67 c[j][k] = (c[j][k]-d*c[i][k]%mod+mod)%mod; 68 } 69 } 70 } 71 return ans; 72 } 73 74 inline double get_dis(int i, int j) { 75 return sqrt((double)((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y))); 76 } 77 78 inline bool same(int i, int j, int k) { 79 return (p[j].x-p[i].x)*(p[k].y-p[i].y) == (p[j].y-p[i].y)*(p[k].x-p[i].x) 80 && (p[k].x>p[i].x&&p[k].x<p[j].x || p[k].x>p[j].x&&p[k].x<p[i].x); 81 } 82 83 int main() { 84 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 85 int T; 86 T = read(); 87 int n, r, mat[MAXN][MAXN]; 88 init(); 89 while(T--) { 90 n = read(); r = read(); 91 rep(i, n) rep(j, n) mat[i][j] = 0; 92 rep(i, n) p[i].x = read(), p[i].y = read(); 93 rep(i, n) { 94 Rep(j, i+1, n) { 95 if(get_dis(i, j) <= r) { 96 bool ok = true; 97 rep(k, n) if(k != i && k != j && same(i, j, k)) { 98 ok = false; break; 99 } 100 if(ok) {// 构造Kirchhoff矩阵 101 mat[i][j] = mat[j][i] = -1; 102 ++mat[i][i]; ++mat[j][j]; 103 } 104 } 105 } 106 } 107 int ans = det(mat, n-1);// Matrix-tree定理 108 if(ans == 0) cout << "-1\n"; 109 else cout << ans << "\n"; 110 } 111 return 0; 112 }