#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;
}

猜你喜欢

转载自www.cnblogs.com/Cao-Yucong/p/12713525.html