1. 程式人生 > >洛谷 P1396 營救

洛谷 P1396 營救

org d+ ctype class empty ios 輸入輸出 生成 -m

題目描述

“咚咚咚……”“查水表!”原來是查水表來了,現在哪裏找這麽熱心上門的查表員啊!小明感動的熱淚盈眶,開起了門……

媽媽下班回家,街坊鄰居說小明被一群陌生人強行押上了警車!媽媽豐富的經驗告訴她小明被帶到了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.二分擁擠度+spfa驗證

屠龍寶刀點擊就送

#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <queue>
#define N 20005

using namespace std;
inline void read(int &x)
{
    register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);ch=getchar()) x=x*10
+ch-0; } struct Edge { int to,val; Edge * next; }edge[N<<1],*head[N]; bool vis[N]; int sumedge,cnt[N],n,m,s,t,dis[N]; inline void ins(int u,int v,int w) { edge[++sumedge].next=head[u]; edge[sumedge].to=v; edge[sumedge].val=w; head[u]=edge+sumedge; } bool check(int Limit) { queue<int>q; q.push(s); for(int i=1;i<=n;i++) vis[i]=0,cnt[i]=0,dis[i]=0x3f3f3f3f; dis[s]=0; cnt[s]=1; vis[s]=1; for(int now=q.front();!q.empty();q.pop(),now=q.front()) { vis[now]=0; if(cnt[now]>=n) return 0; for(Edge * u=head[now];u;u=u->next) { int v=u->to; if(u->val<=Limit&&dis[v]>dis[now]+u->val) { dis[v]=dis[now]+u->val; if(!vis[v]) { vis[v]=1; q.push(v); cnt[v]++; } } } } return dis[t]!=0x3f3f3f3f; } int main() { read(n);read(m);read(s);read(t); for(int x,y,z;m--;) { read(x);read(y);read(z); ins(x,y,z); ins(y,x,z); } int ans; for(int l=0,r=0x3f3f3f3f,mid;l<=r;) { mid=l+r>>1; if(check(mid)) r=mid-1,ans=mid; else l=mid+1; } printf("%d\n",ans); return 0; }

2 spfa

#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <queue>
#define N 20005

using namespace std;
inline void read(int &x)
{
    register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-0;
}
struct Edge
{
    int to,val;
    Edge * next;
}edge[N<<1],*head[N];
bool vis[N];
int sumedge,cnt[N],n,m,s,t,dis[N];
inline void ins(int u,int v,int w)
{
    edge[++sumedge].next=head[u];
    edge[sumedge].to=v;
    edge[sumedge].val=w;
    head[u]=edge+sumedge;
}
void spfa()
{
    queue<int>q;
    q.push(s);
    for(int i=1;i<=n;i++) vis[i]=0,dis[i]=0x3f3f3f3f;
    dis[s]=0;
    vis[s]=1;
    for(int now=q.front();!q.empty();q.pop(),now=q.front())
    {
        vis[now]=0;
        for(Edge * u=head[now];u;u=u->next)
        {
            int v=u->to;
            if(dis[v]>max(u->val,dis[now]))
            {
                dis[v]=max(u->val,dis[now]);
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
int main()
{
    read(n);read(m);read(s);read(t);
    for(int x,y,z;m--;)
    {
        read(x);read(y);read(z);
        ins(x,y,z);
        ins(y,x,z);
    }
    spfa();
    printf("%d\n",dis[t]);
    return 0;
}

3 最小生成樹 代碼來自zsq

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100100
using namespace std;
int x,y,z,n,m,s,t,ans,fa[N];
struct Edge
{
    int x,y,z;
}edge[N];
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-0; ch=getchar();}
    return x*f;
}
int cmp(Edge a,Edge b)
{
    return a.z<b.z;
}
int find(int x)
{
    if(x==fa[x]) return x;
    fa[x]=find(fa[x]);
    return fa[x];
}
int main()
{
    n=read(),m=read(),s=read(),t=read();
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        edge[i].x=x;
        edge[i].y=y;
        edge[i].z=z;
     } 
    for(int i=1;i<=n;i++) fa[i]=i;
    sort(edge+1,edge+1+m,cmp);
    for(int num=0,i=1;i<=m;i++)
    {
        x=edge[i].x,y=edge[i].y;
        int fx=find(x),fy=find(y);
        if(fx==fy) continue;
        fa[fx]=fy;
        num++;
        ans=max(ans,edge[i].z);
        if(num==n-1||find(s)==find(t)) break;
    }
    printf("%d",ans);
    return 0;
}

洛谷 P1396 營救