P1396 营救

P1396 营救
218
通过
571
提交
题目提供者yeszy
标签 二分 图论 并查集 福建省历届夏令营
难度 普及-
题目描述
“咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……
妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了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。

/*
MST最小瓶颈生成树.
定理:MST中的最长边必定小于其他生成树中的最长边. 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#define MAXN 10001
using namespace std;
int n,m,father[MAXN],tot,ss,tt;
struct data
{
    int x,y,z;
}s[MAXN*2];
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x*f;
}
bool cmp(const data &x,const data &y)
{
    return x.z<y.z;
}
int find(int x)
{
    return x!=father[x]? father[x]=find(father[x]):x;
}
int main()
{
    n=read();m=read();ss=read();tt=read();
    for(int i=1;i<=n;i++) father[i]=i;
    for(int i=1;i<=m;i++)
      s[i].x=read(),s[i].y=read(),s[i].z=read();    
    sort(s+1,s+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        int l1=find(s[i].x),l2=find(s[i].y);
        if(l1!=l2) tot++,father[l2]=l1;
        if(find(ss)==find(tt))
        {
            printf("%d",s[i].z);
            return 0;
        }
        if(tot==n-1) break;
    }
    return 0;
}
/*
二分拥挤值.
spfa大于拥挤值的边不选.
然后判能不能到达终点.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 10001
using namespace std;
int n,m,s,t,head[MAXN],tot,dis[MAXN];
bool b[MAXN];
struct data
{
    int v,next,x;
}e[MAXN*4];
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x*f;
}
void add(int u,int v,int x)
{
    e[++tot].v=v;
    e[tot].x=x;
    e[tot].next=head[u];
    head[u]=tot;
}
bool spfa(int x)
{
    int q[MAXN*2]={0},head1=1,tail=0;
    memset(b,0,sizeof(b));
    memset(dis,127/3,sizeof(dis));dis[s]=0;q[++tail]=s;b[s]=true;
    while(head1<=tail)
    {
        int u=q[head1++];b[u]=false;
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(!b[v]&&e[i].x<=x&&dis[v]>dis[u]+e[i].x)
            {
                b[v]=true;
                dis[v]=dis[u]+e[i].x;
                q[++tail]=v;
            }
        }
    }
    if(dis[t]==dis[0]) return false;
    return true;
}
int erfen(int l,int r)
{
    int mid,ans=0;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(spfa(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    return ans;
}
int main()
{
    int x,y,z;
    n=read();m=read();s=read();t=read();
    for(int i=1;i<=m;i++)
    {
        x=read();y=read();z=read();
        add(x,y,z);add(y,x,z);
    }
    printf("%d",erfen(1,10000));
    return 0;
}
原文地址:https://www.cnblogs.com/nancheng58/p/6070779.html