[2015.11.7图论]解题代码集合

  按照“kuangbin带飞”系列和《挑战程序设计竞赛》上给出的练习题进行练习的图论内容。题量比较大,所以只写题号和代码了。纯手撸了这几个题,基本的这几个算法可以说是完全掌握了。

 

poj1251 Jungle Roads 最小生成树 kruskal

题目链接:http://poj.org/problem?id=1251

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 typedef struct Node {
23     int a;
24     int b;
25     int v;
26     friend bool operator < (Node a, Node b) {
27         return a.v > b.v;
28     }
29 }Node;
30 
31 const int maxn = 20010;
32 int pre[maxn];
33 int n, ans;
34 Node p;
35 priority_queue<Node> pq;
36 
37 int find(int x) {
38     return x == pre[x] ? x : pre[x] = find(pre[x]);
39 }
40 
41 bool unite(int x, int y) {
42     x = find(x);
43     y = find(y);
44     if (x != y) {
45         pre[y] = x;
46         return true;
47     }
48     return false;
49 }
50 inline void init() {
51     for (int i = 0; i < maxn; i++) {
52         pre[i] = i;
53     }
54     while (!pq.empty())    pq.pop();
55 }
56 
57 int main() {
58     // freopen("in", "r", stdin);
59     while (~scanf("%d", &n) && n) {
60         init();
61         char a[2], b[2];
62         int cnt = 0;
63         int m, v;
64         ans = 0;
65         n--;
66         for (int i = 0; i < n; i++) {
67             scanf("%s %d", &a, &m);
68             for (int i = 0; i < m; i++) {
69                 scanf("%s %d", &b, &v);
70                 p.a = a[0] - 'A';
71                 p.b = b[0] - 'A';
72                 p.v = v;
73                 pq.push(p);
74             }
75         }
76         while (n) {
77             p = pq.top();
78             pq.pop();
79             if (unite(p.a, p.b)) {
80                 n--;
81                 ans += p.v;
82             }
83         }
84         printf("%d\n", ans);
85     }
86 }
poj1251

 

poj1258 Agri-Net 最小生成树 prim

题目链接:http://poj.org/problem?id=1258

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 const int inf = 0xffffff;
23 const int maxn = 111;
24 int d[maxn];
25 int G[maxn][maxn];
26 int vis[maxn];
27 int n;
28 
29 void init() {
30     memset(vis, 0, sizeof(vis));
31     for(int i = 0; i <= n; i++) d[i] = inf;
32 }
33 
34 int prim(int s) {
35     d[s] = 0;
36     for(int i = 0; i < n; i++) {
37         int u = -1;
38         for(int j = 0; j < n; j++) {
39             if(!vis[j] && (u == -1 || d[u] > d[j])) {
40                 u = j;
41             }
42         }
43         vis[u] = 1;
44         for(int j = 0; j < n; j++) {
45             if(!vis[j]) {
46                 d[j] = min(G[u][j], d[j]);
47             }
48         }
49     }
50     int sp = 0;
51     for(int i = 0; i < n; i++) {
52         sp += d[i];
53     }
54     return sp;
55 }
56 
57 int main() {
58     // freopen("in", "r", stdin);
59     while(~scanf("%d", &n)) {
60         init();
61         for(int i = 0; i < n; i++) {
62             for(int j = 0; j < n; j++) {
63                 scanf("%d", &G[i][j]);
64             }
65         }
66         printf("%d\n", prim(0));
67     }
68 }
poj1258

 

poj1287 Networking 最小生成树 prim(重边)

题目链接:http://poj.org/problem?id=1287

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 const int maxn = 105;
23 const int inf = 0xffffff;
24 int d[maxn];
25 int G[maxn][maxn];
26 int vis[maxn];
27 int n, m;   //n:vertex m:edge
28 
29 void init() {
30     memset(vis, 0, sizeof(vis));
31     for(int i = 0; i <= n; i++) {
32         d[i] = inf;
33         for(int j = 0; j <= n; j++) {
34             G[i][j] = G[j][i] = inf;
35         }
36         G[i][i] = 0;
37     }
38 }
39 
40 int prim(int start) {
41     d[start] = 0;
42     for(int i = 1; i <= n; i++) {
43         int u = -1;
44         for(int j = 1; j <= n; j++) {
45             if(!vis[j]) {
46                 if(u == -1 || d[j] < d[u]) {
47                     u = j;
48                 }
49             }
50         }
51         vis[u] = 1;
52         for(int j = 1; j <= n; j++) {
53             if(!vis[j]) {
54                 d[j] = min(G[u][j], d[j]);
55             }
56         }
57     }
58     int sp = 0;
59     for(int i = 1; i <= n; i++) {
60         sp += d[i];
61     }
62     return sp;
63 }
64 
65 int main() {
66     // freopen("in", "r", stdin);
67     int u, v, w;
68     while(~scanf("%d %d", &n, &m) && n) {
69         init();
70         while(m--) {
71             scanf("%d %d %d", &u, &v, &w);
72             if(w < G[u][v]) {
73                 G[u][v] = G[v][u] = w;
74             }
75         }
76         printf("%d\n", prim(1));
77     }
78 }
poj1258

 

poj2349 Arctic Network 求最小生成树第s+1长的边

题目链接:http://poj.org/problem?id=2349

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 typedef struct Point {
23     int x;
24     int y;
25     double r;
26 }Point;
27 
28 bool cmp(Point x, Point y) {
29     return x.r < y.r;
30 }
31 
32 const int maxn = 222222;
33 priority_queue<int> pq;
34 int n, s, p;
35 int x[maxn],y[maxn];
36 double d[maxn];
37 int pre[maxn];
38 Point poi[maxn];
39 
40 void init() {
41     while(!pq.empty()) pq.pop();
42     for(int i = 0; i <= maxn; i++) {
43         pre[i] = i;
44     }
45 }
46 
47 int find(int x) {
48     return x == pre[x] ? x : pre[x] = find(pre[x]);
49 }
50 
51 bool unite(int x, int y) {
52     x = find(x);
53     y = find(y);
54     if(x != y) {
55         pre[x] = y;
56         return 1;
57     }
58     return 0;
59 }
60 
61 int main() {
62     // freopen("in", "r", stdin);
63     scanf("%d", &n);
64     while(n--) {
65         init();
66         scanf("%d %d", &s, &p);
67         for(int i = 0; i < p; i++) {
68             scanf("%d %d", &x[i], &y[i]);
69         }
70         int cnt = 0;
71         for(int i = 0; i < p; i++) {
72             for(int j = i+1; j < p; j++) {
73                 poi[cnt].x = i;
74                 poi[cnt].y = j;
75                 poi[cnt++].r = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
76             }
77         }
78         sort(poi, poi+cnt, cmp);
79         int cur = 0;
80         for(int i = 0; i < cnt; i++) {
81             if(unite(poi[i].x, poi[i].y)) {
82                 d[cur++] = poi[i].r;
83             }
84         }
85         printf("%.2f\n", d[cur-s]);
86     }
87 }
poj2349

 

poj2236 Wireless Network 并查集

题目链接:http://poj.org/problem?id=2236

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 typedef struct Com {
23     int x;
24     int y;
25 }Com;
26 
27 const int maxn = 20010;
28 int pre[maxn];
29 int con[maxn];
30 int n, d, m;
31 Com com[maxn];
32 
33 bool far(Com c1, Com c2) {
34     return (c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y)<=d*d;
35 }
36 
37 int find(int x) {
38     return x == pre[x] ? x : pre[x] = find(pre[x]);
39 }
40 
41 void unite(int x, int y) {
42     x = find(x);
43     y = find(y);
44     if(x != y) {
45         pre[y] = x;
46     }
47 }
48 inline void init() {
49     memset(con, 0, sizeof(con));
50     for(int i = 0; i < maxn; i++) {
51         pre[i] = i;
52     }
53     m = 0;
54 }
55 
56 int main() {
57     // freopen("in", "r", stdin);
58     int a, b;
59     char cmd[3];
60     while(~scanf("%d %d", &n, &d)) {
61         init();
62         for(int i = 1; i <= n; i++) {
63             scanf("%d %d", &com[i].x, &com[i].y);
64         }
65         while(~scanf("%s", cmd)) {
66             if(cmd[0] == 'S') {
67                 scanf("%d %d", &a, &b);
68                 if(find(a) == find(b)) printf("SUCCESS\n");
69                 else printf("FAIL\n");
70             }
71             else {
72                 scanf("%d", &a);
73                 for(int i = 0; i < m; i++) {
74                     if(far(com[a], com[con[i]])) {
75                         unite(a, con[i]);
76                     }
77                 }
78                 con[m++] = a;
79             }
80         }
81     }
82     return 0;
83 }
poj2236

 

poj2387 Til the Cows Come Home 最短路(floyd不可)

题目链接:http://poj.org/problem?id=2387

  1 // #include <algorithm>
  2 // #include <iostream>
  3 // #include <iomanip>
  4 // #include <cstring>
  5 // #include <climits>
  6 // #include <complex>
  7 // #include <fstream>
  8 // #include <cassert>
  9 // #include <cstdio>
 10 // #include <bitset>
 11 // #include <vector>
 12 // #include <deque>
 13 // #include <queue>
 14 // #include <stack>
 15 // #include <ctime>
 16 // #include <set>
 17 // #include <map>
 18 // #include <cmath>
 19 
 20 // using namespace std;
 21 
 22 // const int maxn = 1111;
 23 // const int inf = 0x7fffff;
 24 // int n, m, u, v, w;
 25 // int G[maxn][maxn];
 26 
 27 // int main() {
 28 //     // freopen("in", "r", stdin);
 29 //     while(~scanf("%d %d", &n, &m)) {
 30 //         for(int i = 1; i <= m; i++) {
 31 //             for(int j = 1; j <= m; j++) 
 32 //                 G[i][j] = G[j][i] = inf;
 33 //             G[i][i] = 0;
 34 //         }
 35 //         for(int i = 1; i <= n; i++) {
 36 //             scanf("%d %d %d", &u, &v, &w);
 37 //             if(G[u][v] > w) 
 38 //                 G[u][v] = G[v][u] = w;
 39 //         }
 40 //         for(int k = 1; k <= m; k++) {
 41 //             for(int i = 1; i <= m; i++) {
 42 //                 for(int j = 1; j <= m; j++) {
 43 //                     if(G[i][j] > G[i][k] + G[k][j]) {
 44 //                         G[i][j] = G[i][k] + G[k][j];
 45 //                     }
 46 //                 }
 47 //             }
 48 //         }
 49 //         printf("%d\n", G[1][m]);
 50 //     }
 51 // }
 52 
 53 
 54 
 55 #include <algorithm>
 56 #include <iostream>
 57 #include <iomanip>
 58 #include <cstring>
 59 #include <climits>
 60 #include <complex>
 61 #include <fstream>
 62 #include <cassert>
 63 #include <cstdio>
 64 #include <bitset>
 65 #include <vector>
 66 #include <deque>
 67 #include <queue>
 68 #include <stack>
 69 #include <ctime>
 70 #include <set>
 71 #include <map>
 72 #include <cmath>
 73 
 74 using namespace std;
 75 
 76 const int maxn = 1111;
 77 const int inf = 0x7fffff;
 78 int d[maxn];
 79 int G[maxn][maxn];
 80 int vis[maxn];
 81 int n, m, u, v, w;
 82 
 83 void init() {
 84     memset(vis, 0, sizeof(vis));
 85     for(int i = 0; i <= m; i++) {
 86         d[i] = inf;
 87         for(int j = 0; j <= m; j++) {
 88             G[i][j] = G[j][i] = inf;
 89         }
 90         G[i][i] = 0;
 91     }
 92 }
 93 
 94 void dijkstra(int start) {
 95     d[start] = 0;
 96     for(int i = 1; i <= m; i++) {
 97         int u = -1;
 98         for(int j = 1; j <= m; j++) {
 99             if(!vis[j]) {
100                 if(u == -1 || d[j] < d[u]) {
101                     u = j;
102                 }
103             }
104         }
105         vis[u] = 1;
106         for(int j = 1; j <= m; j++) {
107             if(!vis[j]) {
108                 d[j] = min(d[u]+G[u][j], d[j]);
109             }
110         }
111     }
112 }
113 
114 int main() {
115     // freopen("in", "r", stdin);
116     while(~scanf("%d %d", &n, &m)) {
117         init();
118         for(int i = 1; i <= n; i++) {
119             scanf("%d %d %d", &u, &v, &w);
120             if(G[u][v] > w) 
121                 G[u][v] = G[v][u] = w;
122         }
123         dijkstra(1);
124         printf("%d\n", d[m]);
125     }
126 }
poj2387

 

poj3268 Silver Cow Party 最短路(两边dijkstra)

题目链接:http://poj.org/problem?id=3268

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <cmath>
 18 
 19 using namespace std;
 20 
 21 
 22 const int maxn = 1001;
 23 const int inf = 0x7ffffff;
 24 int G[maxn][maxn];
 25 int d[maxn];
 26 int vis[maxn];
 27 int b[maxn];
 28 int s,e,v;
 29 int n,m,i,j,x;
 30 
 31 int findMin(int n) {
 32     int minNode  = 0;
 33     int min = inf;
 34     for(int i = 1;i <= n;i++)
 35         if(!vis[i] && d[i] < min) {
 36             minNode = i;
 37             min = d[i];
 38         }
 39     return minNode;
 40 }
 41 
 42 
 43 void dijkstra(int n,int x) {
 44     int i,vnum;
 45     memset(vis,false,sizeof(vis));
 46     for(i = 1;i <= n;i++) {
 47         d[i] = G[x][i];
 48     }
 49     vis[x] = 1;
 50     vnum = 1;
 51     while(vnum  < n) {
 52         int x = findMin(n);
 53         if(x) {
 54             vis[x] = 1;
 55             vnum++;
 56             for(i = 1; i <= n; i++)
 57                 if(!vis[i] && d[x] + G[x][i] < d[i])
 58                     d[i] = G[x][i] + d[x];
 59         }
 60         else break;
 61     }
 62 }
 63 
 64 int findMax(int n) {
 65     int max = 0;
 66     for(int i = 1; i <= n; i++)
 67         if(max < b[i]) max = b[i];
 68     return max;
 69 }
 70 
 71 
 72 void init(int n) {
 73     for(int i = 0; i <= n; i++) {
 74         b[i] = 0;
 75         for(int j = 0; j <= n; j++) {
 76             G[i][j] = inf;
 77         }
 78     }
 79     memset(vis, false, sizeof(vis));
 80 
 81 }
 82 
 83 int main() {
 84     // freopen("in", "r", stdin);
 85     scanf("%d %d %d", &n, &m, &x);
 86     init(n);
 87     for(i = 0;i < m;i++) {
 88         scanf("%d %d %d",&s, &e, &v);
 89         G[s][e] = v;
 90     }
 91     dijkstra(n,x);
 92     for(i = 1;i <= n;i++) {
 93         d[i] != inf ? b[i] = d[i] : b[i] = b[i];
 94     }
 95     for(i = 1;i <= n;i++) {        
 96         for(j = i;j <= n;j++) {
 97             G[i][j] = G[i][j] ^ G[j][i];
 98             G[j][i] = G[i][j] ^ G[j][i];
 99             G[i][j] = G[i][j] ^ G[j][i];
100         }
101     }
102     dijkstra(n,x);
103     for(i = 1;i <= n;i++) {
104         d[i] != inf ? b[i] += d[i] : b[i] = b[i];
105     }
106     printf("%d\n", findMax(n));
107     return 0;
108 }
poj3268

邻接表,优先队列优化做法:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 typedef pair<int, int> PII;
23 const int inf = 100010;
24 const int maxn = 1111;
25 
26 typedef struct Edge {
27     int v;
28     int w;
29     Edge(int vv, int ww) : v(vv), w(ww) {}
30 };
31 
32 vector<Edge> G1[maxn], G2[maxn];
33 int n, m, x;
34 int u, v, w;
35 int d1[maxn], d2[maxn];
36 int ans;
37 
38 void dijkstra(int s, vector<Edge>* G, int* d) {
39     priority_queue<PII, vector<PII>, greater<PII> > pq;
40     for(int i = 1; i <= n; i++) d[i] = inf;
41     d[s] = 0;
42     pq.push(PII(0, s));
43     while(!pq.empty()) {
44         PII p = pq.top(); pq.pop();
45         int v = p.second;
46         if(d[v] < p.first) continue;
47         for(int i = 0; i < G[v].size(); i++) {
48             if(d[G[v][i].v] > d[v] + G[v][i].w) {
49                 d[G[v][i].v] = d[v] + G[v][i].w;
50                 pq.push(PII(d[G[v][i].v], G[v][i].v));
51             }
52         }
53     }
54 }
55 
56 int main() {
57     // freopen("in", "r", stdin);
58     scanf("%d %d %d", &n, &m, &x);
59     for(int i = 0; i < m; i++) {
60         scanf("%d %d %d", &u, &v, &w);
61         G1[u].push_back(Edge(v, w));
62     }
63     dijkstra(x, G1, d1);
64     for(int i = 1; i <= n; i++) {
65         for(int j = 0; j < G1[i].size(); j++) {
66             G2[G1[i][j].v].push_back(Edge(i, G1[i][j].w));
67         }
68     }
69     dijkstra(x, G2, d2);
70     ans = 0;
71     for(int i = 2; i <= n; i++) {
72         if(i == x) continue;
73         ans = max(ans, d1[i]+d2[i]);
74     }
75     printf("%d\n", ans);
76     return 0;
77 }
poj3268

 

 

 

hdoj1875 畅通工程再续 最小生成树(注意精度)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1875

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19 
 20 using namespace std;
 21 
 22 typedef struct Point {
 23     int x;
 24     int y;
 25     double r;
 26 }Point;
 27 
 28 int cmp(Point x, Point y) {
 29     return x.r < y.r;
 30 }
 31 
 32 const int maxn = 10000;
 33 int pre[maxn];
 34 int x[maxn];
 35 int y[maxn];
 36 int c, cnt;
 37 Point poi[maxn];
 38 
 39 int find(int x) {
 40     int r = x;
 41     int t;
 42     while(x != pre[x])
 43         x = pre[x];
 44     while(r != x) {
 45         t = pre[r];
 46         pre[r] = x;
 47         r = t;
 48     }
 49     return x;
 50 }
 51 
 52 void unite(int x, int y) {
 53     int xx = find(x);
 54     int yy = find(y);
 55     if(xx != yy) {
 56         pre[xx] = yy;
 57     }
 58 }
 59 
 60 void init() {
 61     for(int i = 0; i <= c; i++) {
 62         pre[i] = i;
 63     }
 64 }
 65 
 66 int main() {
 67     // freopen("in", "r", stdin);
 68     int T;
 69     scanf("%d", &T);
 70     while(T--) {
 71         scanf("%d", &c);
 72         cnt = 0;
 73         for(int i = 0; i < c; i++) {
 74             scanf("%d %d", &x[i], &y[i]);
 75         }
 76         for(int i = 0; i < c-1; i++) {
 77             for(int j = i+1; j < c; j++) {
 78                 double rr = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
 79                 poi[cnt].x = i;
 80                 poi[cnt].y = j;
 81                 poi[cnt++].r = rr;
 82             }
 83         }
 84         init();
 85         sort(poi, poi+cnt, cmp);
 86         double ans = 0;
 87         for(int i = 0; i < cnt; i++) {
 88             if(find(poi[i].x != find(poi[i].y)) && poi[i].r >= 10.0000 && poi[i].r <= 1000.00001) {
 89                 unite(poi[i].x, poi[i].y);
 90                 ans += poi[i].r;
 91             }
 92         }
 93         // for(int i = 0; i < c; i++) printf("%d ", pre[i]);
 94         // printf("\n");
 95         int flag = 1;
 96         int s = 0;
 97         for(int i = 0; i < c; i++) {
 98             if(pre[i] == i) {
 99                 s++;
100             }
101             if(s > 1) {
102                 flag = 0;
103                 break;
104             }
105         }
106         if(flag) printf("%.1lf\n", ans * 100);
107         else printf("oh!\n");
108     }
109     return 0;
110 }
hdoj1875

 

posted @ 2015-11-07 20:03  Kirai  阅读(293)  评论(0编辑  收藏  举报