您的位置:首页 > 其它

poj 2455 Secret Milking Machine 最大流+二分查找

2012-11-21 07:55 459 查看
本题的关键在于理解题意:本题不是求最短路,而是要求路上的最长的一部分最小,故可以用二分法解决,至于路的条数,则可以求图的最大流

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
const int INF=1<<30;
using namespace std;
int st[202][202],m,n,h[202],vh[202],mi,ma,flag,sum,vi[202],k;
struct ss
{
int u,v,w;
}map[40500];
queue<int> q;
void dfs()
{
while(!q.empty())
q.pop();
memset(h,0,sizeof(h));
memset(vh,0,sizeof(vh));
vh[0]=m;
while(!q.empty())
{
int fr=q.front();
q.pop();
if(fr==1)
{
return;
}
for(int i=1;i<=m;i++)
{
if(st[i][fr]&&!h[i])
{
h[i]=h[fr]+1;
q.push(i);
vh[h[i]]++;
}
}
}
}
int seek(int cu)
{
for(int i=1;i<=m;i++)
if(st[cu][i]&&h[cu]==h[i]+1)
return i;
return -1;
}
int xz(int i)
{
int mi=m;
for(int j=1;j<=m;j++)
{
if(st[i][j]>0)
mi=mi<h[j]?mi:h[j];
}
return mi;
}
int sap()
{
dfs();
vi[1]=0;
int i=1;
while(h[1]<m)
{
int j=seek(i);
if(j>0)
{
vi[j]=i;
i=j;
if(i==m)
{
int v=m;
int flow=INF;
while(vi[v]>0)
{
if(st[vi[v]][v]<flow)
flow=st[vi[v]][v];
v=vi[v];

}
v=m;
while(vi[v]>0)
{
st[vi[v]][v]-=flow;
st[v][vi[v]]+=flow;
v=vi[v];
}
sum+=flow;
i=1;
}
}
else
{
vh[h[i]]--;
if(vh[h[i]]==0)
return sum;
int x;
x=xz(i);
h[i]=x+1;
vh[h[i]]++;
if(i!=1)
i=1;
}

}
return sum;
}
int ef()
{
int x,y;
x=mi;
y=ma;
int mid;
while(y>x)
{
sum=0;
mid=(x+y)/2;
int i,j;
memset(st,0,sizeof(st));
for(i=0;i<k;i++)
{
if(map[i].w<=mid)
{

st[map[i].u][map[i].v]++;
st[map[i].v][map[i].u]++;
}

}
sum=sap();
if(sum>=n)
y=mid;
else
x=mid+1;

}
return y;
}
int main()
{
int a,b,c,i;

while(~scanf("%d%d%d",&m,&k,&n)&&(m+k+n))
{
mi=INF;
ma=-1;
memset(map,0,sizeof(map));
for(i=0;i<k;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[i].u=a;
map[i].v=b;
map[i].w=c;
if(c<mi)
mi=c;
if(c>ma)
ma=c;
}
int ff=ef();
printf("%d\n",ff);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: