当前位置: 代码迷 >> 综合 >> POJ 2112 网络流英文阅读题
  详细解决方案

POJ 2112 网络流英文阅读题

热度:50   发布时间:2024-01-20 20:29:48.0

这题的题意佷坑爹啊。。。虽说是很明显的二分题。

说有K个奶牛机编号1-K,有C头奶牛,编号k+1-K+C这样形成了K+C阶的距离矩阵。每台奶牛机可以处理T只奶牛

开始呢... 只把机器和奶牛连了边,机器与奶牛的边全部去掉了... 无限WA...

后来想.. 如果流通过机器之间传到奶牛呢= =!!!有剩余流就可以做到了!

顿悟,狂敲,交... 无限WA....

后来看了看题,机器之间的流不算流啊... 只要牛进入机器产奶就行了= =,距离只是个过程啊.. 相当于转移过程,这不是流啊...

然后... 用floyd把最短路构建出来,因为最短路嘛,一定会比单边的长...但是... 这个边好像是和诶.... 不是单边诶... 难道说 莫名其妙的AC了= =

#include<iostream>
#include<cstdio>
#include<string>
#define MN 255
#define INF INT_MAX>>2
using namespace std;struct edge{int len,cap;
}map[MN][MN];
int que[MN],pre[MN],vis[MN],a[MN];
int K,C,M,s,t,l,r,ans;void setG()
{int i,j,k;l=1;r=200000;s=0;t=K+C+1;memset( map,0,sizeof(map) );for( i=1;i<=K+C;i++ )for( j=1;j<=K+C;j++ ){scanf( "%d",&map[i][j].len );if( map[i][j].len==0 )map[i][j].len=INF;}for( k=1;k<=K+C;k++ )for( i=1;i<=K+C;i++ )for( j=1;j<=K+C;j++ )if( map[i][j].len>map[i][k].len+map[k][j].len )map[i][j].len=map[i][k].len+map[k][j].len;
}void initG( int len )
{int i,j;ans=0;for( i=0;i<=K+C+1;i++ )for( j=0;j<=K+C+1;j++ )map[i][j].cap=0;for( i=1;i<=K;i++ )for( j=K+1;j<=K+C;j++ )map[i][j].cap=map[i][j].len<=len?1:0;for( i=1;i<=K;i++ )map[s][i].cap=M;for( i=K+1;i<=K+C;i++ )map[i][t].cap=1;
}bool bfs( int len )
{int head=0,foot=0;memset( vis,0,sizeof(vis) );que[foot++]=s;vis[s]=true;a[s]=INT_MAX;while( head<foot ){int u=que[head++];for( int i=0;i<=t;i++ ){if( !vis[i]&&map[u][i].cap ){vis[i]=true;que[foot++]=i;pre[i]=u;a[i]=min( a[u],map[u][i].cap );if( i==t )return true;}}}return false;
}bool work(int len)
{int m;while( bfs(len) ){m=t;ans+=a[t];while( m!=s ){map[pre[m]][m].cap-=a[t];map[m][pre[m]].cap+=a[t];m=pre[m];}}if( ans==C ) return true;else return false;
}int main()
{while( scanf("%d%d%d",&K,&C,&M)!=EOF ){int mid;setG();while( (mid=(l+r)/2)&&l<r ){initG(mid);if( work(mid) ) r=mid;else l=mid+1;}printf( "%d\n",mid );}return 0;
}