二分最大边 记为lim 不超过lim的边容量记为1 否则记为0 再抽象一个源点 从源点到1的容量为题目所给的t 然后以此建图 看是否满流
感觉网络流的抽象建图很关键 这道题看了别人的建图才会的...
符合条件就是1 即存在 反之就是0 即不存在 这样就把一个记录路径长度的图转化为记录路径是否可行的图 每增广一次图中就少一条路 长知识了!
using namespace std;
struct node1
{
int u;
int v;
int w;
};
struct node2
{
int v;
int w;
int next;
};
node1 pree[80010];
node2 edge[160010];
int first[210],dis[210],gap[210],cur[210],pre[210];
int n,m,t,num,sum,ans,ss,ee;
void binsearch(int l,int r);
void build(int lim);
void addedge(int u,int v,int w);
void isap();
void bfs();
int main()
{
int i,u,v,w,minn,maxx;
while(scanf("%d%d%d",&n,&m,&t)!=EOF)
{
num=0,minn=N,maxx=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
num++;
pree[num].u=u;
pree[num].v=v;
pree[num].w=w;
num++;
pree[num].u=v;
pree[num].v=u;
pree[num].w=w;
if(w<minn) minn=w;
if(w>maxx) maxx=w;
}
binsearch(minn,maxx);
printf("%d\n",ans);
}
return 0;
}
void binsearch(int l,int r)
{
int lim;
ans=r;
while(l<=r)
{
lim=(l+r)/2;
build(lim);
isap();
if(sum>=t)
{
r=lim-1;
ans=lim;
}
else
{
l=lim+1;
}
}
return;
}
void build(int lim)
{
int i;
memset(first,-1,sizeof(first));
num=0,ss=n+1,ee=n;
addedge(ss,1,t);
addedge(1,ss,0);
for(i=1;i<=m*2;i++)
{
if(pree[i].w<=lim)
{
addedge(pree[i].u,pree[i].v,1);
addedge(pree[i].v,pree[i].u,0);
}
else
{
addedge(pree[i].u,pree[i].v,0);
}
}
return;
}
void addedge(int u,int v,int w)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=first[u];
first[u]=num++;
return;
}
void isap()
{
int j,u,v,flow,minn;
memcpy(cur,first,sizeof(first));
memset(pre,-1,sizeof(pre));
bfs();
num=n+1,sum=0,u=ss,flow=N;
while(dis[ss]<num)
{
int &i=cur[u];
for(;i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(edge[i].w>0&&dis[v]+1==dis[u])
{
pre[v]=i;
u=v,flow=min(flow,edge[i].w);
if(u==ee)
{
while(u!=ss)
{
j=pre[u];
edge[j].w-=flow;
edge[j^1].w+=flow;
u=edge[j^1].v;
}
sum+=flow,flow=N;
}
break;
}
}
if(i==-1)
{
if(--gap[dis[u]]==0) break;
cur[u]=first[u];
minn=num-1;
for(j=first[u];j!=-1;j=edge[j].next)
{
if(edge[j].w>0)
{
minn=min(minn,dis[edge[j].v]);
}
}
dis[u]=minn+1;
gap[dis[u]]++;
if(u!=ss)
{
u=edge[pre[u]^1].v;
}
}
}
return;
}
void bfs()
{
queue <int> que;
int i,u,v;
memset(dis,-1,sizeof(dis));
memset(gap,0,sizeof(gap));
que.push(ee);
dis[ee]=0;
while(!que.empty())
{
u=que.front();
que.pop();
gap[dis[u]]++;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(dis[v]==-1)
{
dis[v]=dis[u]+1;
que.push(v);
}
}
}
return;
}