营救

题目描述

“咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……

妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了t区,而自己在s区。

该市有m条大道连接n个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从s至t的路线,使得经过道路的拥挤度最大值最小。

输入输出格式

输入格式:

第一行四个数字n,m,s,t。

接下来m行,每行三个数字,分别表示两个区和拥挤度。

(有可能两个区之间有多条大道相连。)

输出格式:

输出题目要求的拥挤度。

输入输出样例

输入样例#1:
3 3 1 3							
1 2 2
2 3 1
1 3 3
输出样例#1:
2

说明

数据范围

30% n<=10

60% n<=100

100% n<=10000,m<=2n,拥挤度<=10000

题目保证1<=s,t<=n且s<>t,保证可以从s区出发到t区。

样例解释:

小明的妈妈要从1号点去3号点,最优路线为1->2->3。

题目大意

两点之间 可到达路径的最大边的最小值

题解

(1)克鲁斯卡尔 贪心加边 知道联通

(2)spfa dis[i]表示i到t的最大边的最小值

代码

kruskal

#include<iostream>
#include<algorithm>
#include<cstdio>
#define maxn 10002
using namespace std;

int n,m,s,t,cnt,k,x,y,z,fa[maxn];

struct Edge{
    int x,y,z;
}edge[maxn<<2];

bool cmp(Edge a,Edge b){
    return a.z<b.z;
}

int f(int x){
    return fa[x]==x?x:fa[x]=f(fa[x]);
}

int main(){
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        edge[++cnt].x=x;edge[cnt].y=y;edge[cnt].z=z;
        edge[++cnt].x=y;edge[cnt].y=x;edge[cnt].z=z;
    }
    for(int i=1;i<=n;i++)fa[i]=i;
    sort(edge+1,edge+cnt+1,cmp);
    for(k=1;k<=cnt;k++){
        if(f(s)==f(t))break;
        int fx=f(edge[k].x),fy=f(edge[k].y);
        if(fx!=fy){
            fa[fx]=fy;
        }
    }
    printf("%d
",edge[k].z);
    return 0;
}

spfa

#include<iostream>
#include<queue>
#include<cstring> 
#include<cstdio>
#define maxn 10003
using namespace std;

int n,m,s,t,x,y,z,a,sumedge;
int inq[maxn],dis[maxn],head[maxn];
queue<int>q;

struct Edge{
    int x,y,z,nxt;
    Edge(int x=0,int y=0,int z=0,int nxt=0):
        x(x),y(y),z(z),nxt(nxt){}
}edge[maxn<<2];

void add(int x,int y,int z){
    edge[++sumedge]=Edge(x,y,z,head[x]);
    head[x]=sumedge;
}

void spfa(){
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0;
    q.push(s);inq[s]=1;
    while(!q.empty()){
        int now=q.front();q.pop();inq[now]=0;
        for(int i=head[now];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(dis[v]>max(dis[now],edge[i].z)){
                dis[v]=max(dis[now],edge[i].z);
                if(!inq[v]){
                    inq[v]=1;
                    q.push(v); 
                }
            }
        }
    } 
}

int main(){
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
    }
    spfa();
    printf("%d
",dis[t]);
    return 0;
}
原文地址:https://www.cnblogs.com/zzyh/p/7435714.html