#luogu整理 P1396 营救:最短路算法
并查集#2
luogu P1396 营救 :生成树
题面描述
给定n个点和m条边,每条边有一定的权值,求找出一条路径,使得这条路径上的每一条边的权值的最大值最小。
思路
用邻接表存储边,用广度优先搜索遍历整棵树,得到答案。整体操作类似最短路,只不过中间需要更改。这个东西的思路还有点类似dp,但是我怎么写也写不出来。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct EDGE{
int x,y,z,nxt;
}edge[10099];
int n,m;
int s,t;
int cnt = 0;
int head[10099];
int vis[10099];
int ans[10099];
int ans1[10099];
void add_edge(int x,int y,int z){
cnt++;
edge[cnt].x = x;
edge[cnt].y = y;
edge[cnt].z = z;
edge[cnt].nxt = head[x];
head[x] = cnt;
}
queue<int> q;
int main(){
memset(ans, 10099, sizeof(ans));
memset(ans1,0,sizeof(ans1));
cin >> n >> m >> s >> t;
for(int i = 1;i <= m; i++){
int x,y,z;
cin >> x >> y >> z;
add_edge(x,y,z);
add_edge(y,x,z);
}
q.push(s);
vis[s] = 1;
ans[s] = 0;
ans[s] = 0;
cout << s << ' ';
int anss = 10099;
while(!q.empty()){
int x = q.front();
q.pop();
for(int i = head[x];i;i = edge[i].nxt){
if(vis[edge[i].y]) continue;
vis[edge[i].y] = 1;
q.push(edge[i].y);
cout << edge[i].y << ' ';
ans1[edge[i].y] = max(ans1[edge[i].x],edge[i].z);
ans[edge[i].y] = min(ans[edge[i].y],max(ans1[edge[i].x], edge[i].z));
if(edge[i].y == t) anss = min(anss,ans1[t]);
}
}
cout << endl;
cout << endl;
for(int i = 1;i <= n;i++){
cout << ans[i] << ':' << ans1[i] << endl;
}
// int ANS = 100000;
// for(int i = head[t];i;i = edge[i].nxt){
// ANS = min(ANS,ans[edge[i].y]);
// }
// cout << ANS << endl;
cout << ans[t] << endl;
cout << anss << endl;
return 0;
}