玲珑杯 Round15 E咸鱼旅行 最小生成树+BFS
题目链接:http://www.ifrog.cc/acm/problem/1126
maxn = 500005. 不然RE。。。。。
思路:跑一遍最小生成树然后bfs找一下即可。
wa了N次,发现自己并没有真正理解并查集的合并:x = find(u), y = find(v), p[x] = y,等价于先find(u) find(v)之后(需要路径压缩)p[p[u]] = p[v] 或者p[p[v]] = p[u]
不过纯粹自己写kruskal + bfs + 并查 AC的感觉还是很爽的。
代码:
1 #define maxn 500005 2 #define maxm 500005 3 struct node{ 4 int to, val; 5 node(int t, int v): to(t), val(v) {} 6 }; 7 int edge[maxm], u[maxm], v[maxm]; 8 int p[maxn], f[maxn]; 9 int n, m, s, t; 10 11 typedef pair<int, int> P; 12 vector<node> G[maxn]; 13 queue<node> q; 14 short vis[maxn]; 15 16 int findp(int x){ 17 return x == p[x]? x: p[x] = findp(p[x]); 18 } 19 int cmp(int i, int j){ 20 return edge[i] < edge[j]; 21 } 22 23 int kruskal(){ 24 for(int i = 0; i < n; i++) 25 G[i].clear(); 26 memset(vis, 0, sizeof(vis)); 27 int cnt = 0; 28 for(int i = 0; i < n; i++) 29 p[i] = i; 30 for(int i = 0; i < m; i++) 31 f[i] = i; 32 sort(f, f + m, cmp); 33 /* 34 for(int i = 0; i < m; i++) 35 printf("%d\t", f[i]); 36 printf("\n"); 37 */ 38 for(int ii = 0; ii < m; ii++){ 39 int i = f[ii]; 40 int tmu = u[i], tmv = v[i]; 41 int x = findp(tmu), y = findp(tmv); 42 if(x == y) 43 continue; 44 p[x] = y; 45 G[tmu].push_back(node(tmv, edge[i])); 46 G[tmv].push_back(node(tmu, edge[i])); 47 cnt++; 48 if(cnt >= n - 1) 49 break; 50 } 51 if(cnt != n - 1) 52 return -1; 53 54 q.push(node(s, 0)); 55 vis[s] = 1; 56 while(!q.empty()){ 57 node tm = q.front(); 58 q.pop(); 59 if(tm.to == t){ 60 return tm.val; 61 } 62 for(int i = 0; i < G[tm.to].size(); i++){ 63 node tmn = G[tm.to][i]; 64 if(!vis[tmn.to]){ 65 vis[tmn.to] = 1; 66 q.push(node(tmn.to, max(tmn.val, tm.val))); 67 } 68 } 69 } 70 71 return -1; 72 } 73 74 int main(){ 75 scanf("%d %d", &n, &m); 76 for(int i = 0; i < m; i++){ 77 int tmu, tmv; 78 scanf("%d %d %d", &tmu, &tmv, &edge[i]); 79 u[i] = --tmu, v[i] = --tmv; 80 } 81 scanf("%d %d", &s, &t); 82 s--, t--; 83 int ans = kruskal(); 84 printf("%d\n", ans); 85 }
题目:
1126 - 咸鱼旅行
Time Limit:3s Memory Limit:128MByte
Submissions:539Solved:95
DESCRIPTION
这个地区可以看作是一个无向图,N个点M条边组成。每个边有一个边权。我们定义一条路径的花费,就是这条路径上最大的边权。
现在有一条咸鱼,想从S走到T,徒步旅行。
咸鱼于是找到了你,想让你告诉他从S到T的最小花费。
INPUT
第一行两个整数,N,M。满足(1 <= N <= 10^5, 0 <= M <= 5*10^5)
接下来M行,每行三个整数U,V,C。表示有一个连接U点和V点的边,且边权是C。(1<=C<=10^9)
接下来一个行是两个整数S,T(1<=S,T<=n)
OUTPUT
输出答案,如果S不能到达T,输出-1
SAMPLE INPUT
5 5
1 2 1
2 3 1
3 4 1
4 5 1
5 1 1
1 3
SAMPLE OUTPUT
1