AC日记——城市 洛谷 P1401

题目描述

N(2<=n<=200)个城市,M(1<=m<=40000)条无向边,你要找T(1<=T<=200)条从城市1到城市N的路,使得最长的边的长度最小,边不能重复用。

输入输出格式

输入格式:

第1行三个整数N,M,T用空格隔开。

第2行到P+1行,每行包括三个整数Ai,Bi,Li表示城市Ai到城市Bi之间有一条长度为Li的道路。

输出格式:

输出只有一行,包含一个整数,即经过的这些道路中最长的路的最小长度。

输入输出样例

输入样例#1:
7 9 2
1 2 2
2 3 5
3 7 5
1 4 1
4 3 1
4 5 7
5 7 1
1 6 3
6 7 3
输出样例#1:
5

思路:

  网络流;

  二分答案;

  然后删边;

  然后看最大流是否大于T;

来,上代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

#define maxn 205
#define INF 0x7fffffff

using namespace std;

struct EdgeType {
    int v,l,e,f;
};
struct EdgeType edge[maxn*maxn*4];

int s,t,deep[maxn];
int n,m,T,cnt=1,head[maxn],maxl,minl=0x7fffffff;

char Cget;

inline void in(int &now)
{
    now=0,Cget=getchar();
    while(Cget>'9'||Cget<'0') Cget=getchar();
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
}

bool bfs()
{
    queue<int>que;
    for(int i=s;i<=t;i++) deep[i]=-1;
    deep[s]=0,que.push(s);
    while(!que.empty())
    {
        int now=que.front();que.pop();
        for(int i=head[now];i;i=edge[i].e)
        {
            if(deep[edge[i].v]<0&&edge[i].f>0)
            {
                deep[edge[i].v]=deep[now]+1;
                if(edge[i].v==t) return true;
                que.push(edge[i].v);
            }
        }
    }
    return false;
}

int flowing(int now,int flow)
{
    if(now==t||flow<=0) return flow;
    int oldflow=0;
    for(int i=head[now];i;i=edge[i].e)
    {
        if(deep[edge[i].v]!=deep[now]+1||edge[i].f<=0) continue;
        int pos=flowing(edge[i].v,min(flow,edge[i].f));
        if(pos>0)
        {
            flow-=pos;
            oldflow+=pos;
            edge[i].f-=pos;
            edge[i^1].f+=pos;
            if(flow==0) return oldflow;
        }
    }
    if(oldflow==0) deep[now]=-1;
    return oldflow;
}

bool check(int pos)
{
    for(int i=2;i<=cnt;i+=2)
    {
        edge[i^1].f=0;
        if(edge[i].l<=pos) edge[i].f=1;
        else edge[i].f=0;
    }
    int ans=0;
    while(bfs())
    ans+=flowing(s,INF);
    if(ans>=T) return true;
    else return false;
}

int main()
{
    in(n),in(m),in(T);
    int u,v,li;s=1,t=n;
    while(m--)
    {
        in(u),in(v),in(li);if(li>maxl) maxl=li;if(li<minl) minl=li;
        edge[++cnt].v=v,edge[cnt].l=li,edge[cnt].e=head[u],head[u]=cnt;
        edge[++cnt].v=u,edge[cnt].l=li,edge[cnt].e=head[v],head[v]=cnt;
        edge[++cnt].v=u,edge[cnt].l=li,edge[cnt].e=head[v],head[v]=cnt;
        edge[++cnt].v=v,edge[cnt].l=li,edge[cnt].e=head[u],head[u]=cnt;
    }
    int l=minl,r=maxl,ans,mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6647097.html