[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

  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 }
View Code

 // hdu 4081

 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 }
View Code

// UVA 10600

  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 }
View Code

 // UVA 10462

  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 }
View Code

// 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\n");
89         else printf("%.2lf\n", ans);
90     }
91     return 0;
92 }
View Code

// UVA 11183

  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 }
View Code

// 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" << "\n\n";
105         else cout << ans-sum << " " << pos-m << "\n\n";
106     }
107     return 0;
108 }
View Code

// 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\n", ans); //cout << ans << "\n";
112     }
113     return 0;
114 }
View Code

// UVA 10766

 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 }
View Code

// hdu 4305

  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 }
View Code

 

posted @ 2019-10-15 17:42  pupil337  阅读(176)  评论(0编辑  收藏  举报