题意: 保留图中的一些边,使得每条边只走一次的情况下,起点到终点至少有t条路径,求满足此要求的图中最长的边最短为多少?
二分答案,然后用网络流判断可行性。
#include<stdio.h>
#include<string.h>
using namespace std;
const int inf=1<<30;
const int maxn=301;
struct
{
int to,w,next;
}e[100001];
int edge[maxn][maxn];
int lon,head[maxn];
int edgeini(int n)
{
memset(head,-1,sizeof(head));
lon=-1;
}
int edgemake(int from,int to,int w)
{
e[++lon].to=to;
e[lon].w=w;
e[lon].next=head[from];
head[from]=lon;
}
int level[maxn],que[maxn];
int makelevel(int s,int t)
{
memset(level,0,sizeof(level));
level[s]=1;
int top=0;
que[++top]=s;
for(int i=1;i<=top;i++)
{
int u=que[i];
if(u==t) return(1);
for(int k=1;k<=t;k++)
if(!level[k]&&edge[u][k])
{
que[++top]=k;
level[k]=level[u]+1;
}
}
return(0);
}
int dfs(int now,int maxf,int t)
{
if(now==t)return(maxf);
int ret=0;
for(int k=1;k<=t;k++)
if(edge[now][k]&&level[k]==level[now]+1)
{
int f=dfs(k,min(maxf-ret,edge[now][k]),t);
edge[now][k]-=f;
edge[k][now]+=f;
ret+=f;
if(ret==maxf) return(ret);
}
return(ret);
}
int dinic(int s,int t)
{
int ans=0;
while(makelevel(s,t)) ans+=dfs(s,inf,t);
return(ans);
}
int main()
{
int n,p,t;
scanf("%d %d%d",&n,&p,&t);
edgeini(n);
int bg=0;
for(int i=1;i<=p;i++)
{
int from,to,w;
scanf("%d %d %d",&from,&to,&w);
edgemake(from,to,w);
edgemake(to,from,w);
if(w>bg) bg=w;
}
int sm=0;
while(sm<bg)
{
int mid=(sm+bg)>>1;
memset(edge,0,sizeof(edge));
for(int i=1;i<=n;i++)
for(int k=head[i];k!=-1;k=e[k].next)
if(e[k].w<=mid)
edge[i][e[k].to]+=1;
if(dinic(1,n)>=t)
bg=mid;
else
sm=mid+1;
}
printf("%d\n",sm);
return 0;
}