1. 程式人生 > >POJ-2112 Optimal Milking(floyd+最大流+二分)

POJ-2112 Optimal Milking(floyd+最大流+二分)

存在 AC d+ display i++ IV for 對角線 while

題目大意:

有k個擠奶器,在牧場裏有c頭奶牛,每個擠奶器可以滿足m個奶牛,奶牛和擠奶器都可以看成是實體,現在給出兩個實體之間的距離,如果沒有路徑相連,則為0,現在問你在所有方案裏面,這c頭奶牛需要走的最大距離的最小值。

分析:

先將題目給出來的距離矩陣跑一下 Floyd 求出全源最短路方便後面建圖,

這裏註意一下除了對角線的點若有其他點為 0 則應將其值設置為 INF 代表不可達

在使用最大流判斷是否存在解的時候,要對每個解都重新建圖。

建圖需要一個超級源點,把所有的奶牛與源點相連,容量設置為1

把所有的擠奶器與匯點相連,容量為m

然後對於擠奶器和奶牛的距離不超過判斷的解的距離的連邊,容量設置為1

然後求解即可。如果最大流 == 牛的總數說明可行

AC代碼:

技術分享圖片
    DC.AddEdge(0,k+i,1);
    for(int i=1 ; i<=k ; i++)
    DC.AddEdge(i,n,m);
    for(int i=k+1 ; i<=k+c ; i++)
    for(int j=1 ; j<=k ; j++)
    if(mp[i][j]<=mid)
    DC.AddEdge(i,j,INF);
    return (DC.Maxflow()==c);
}

int main( )
{
   int k,c,m;
   while
(scanf("%d%d%d",&k,&c,&m)!=EOF) { for(int i=1 ; i<=k+c ; i++) for(int j=1 ; j<=k+c ; j++) { scanf("%d",&mp[i][j]); if(i!=j&&mp[i][j]==0) mp[i][j]=INF; } FD(k,c); int ans; while(L<=R) {
int mid = (L+R)>>1; if(!ok(mid,k,c,m)) L = mid+1; else { ans=mid; R=mid-1; } } printf("%d\n",ans); } return 0; }
View Code

POJ-2112 Optimal Milking(floyd+最大流+二分)