日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ - 2112 Optimal Milking(二分+二分图最大匹配-多重匹配(修改匈牙利实现)+Floyd求最短路)

發布時間:2024/4/11 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ - 2112 Optimal Milking(二分+二分图最大匹配-多重匹配(修改匈牙利实现)+Floyd求最短路) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出n個牛奶機器,再給出m只奶牛,每個機器只能讓最多k只牛一起擠奶,現在問如何分配奶牛,能讓最遠的那只奶牛到達機器的距離最小

題目分析:很綜合的一道題目了,不算很難,但比較難想,首先看到求最大值的最小值或者求最小值的最大值的這種問題,第一反應肯定是二分了,我們可以二分答案,也就是最遠距離,不過在check之前,我們先要對給出的鄰接矩陣跑一遍floyd,以保證兩點之間的距離是他們的最短路,這樣才能符合題意,然后我們該怎么check呢,每次二分出最遠距離后,對于最短路小于等于該距離的兩點就可以建邊了,注意!之前二分圖匹配的題比如男孩女孩匹配,建邊的時候讓男孩指向女孩也行,女孩指向男孩也可以,最后不影響結果的,但這個題目不一樣,我們的目的是要讓所有的奶牛能找到一個機器,而不是讓所有的機器都找到一個奶牛,所以我們這里建邊要用奶牛指向機器,然后跑匈牙利的時候也要以奶牛去匹配機器才行,這里涉及到了一點新知識,也就是二分圖的多重匹配問題,其實和單一匹配的思路是一樣的,就是將match[N]變為了match[N][N],就可以了,第一維維護的是哪個點,第二維維護的是有哪些點與之匹配,若當前的機器還沒有匹配夠足夠的奶牛,也就是還沒有達到上限k,我們就直接將其匹配即可,若達到了上限,我們就看一下能不能讓其他的奶牛去別的機器,也就是進入dfs尋找增廣路

題外話,因為floydWA了好幾發,好久沒寫最短路了,也是今天才知道floyd的三層枚舉順序是固定的。。是我太菜了嘛,大概可以這樣理解,最外層枚舉中間斷點k,內層枚舉起點i和終點j,相當于讓i到j之間的點不斷松弛,必須固定k不能動,不然k一動的話答案就錯了

具體實現看代碼吧,應該不難懂,三個很簡單的算法組合出來了這個題目

代碼:

#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=250;int n,m,limit;vector<int>match[N];//這里我為了方便記錄第二維的長度,用vector代替了二維數組bool maze[N][N],vis[N];int d[N][N];bool dfs(int x) {for(int i=1;i<=n;i++){if(maze[x][i]&&!vis[i]){vis[i]=true;if(match[i].size()<limit)//如果當前與之匹配的點還沒滿,直接加入即可{match[i].push_back(x);return true;}for(int j=0;j<limit;j++)//否則依次尋找增廣路{if(dfs(match[i][j])){match[i][j]=x;return true;}}}}return false; }bool check(int x) {memset(maze,false,sizeof(maze));//每次跑匈牙利之前都要記得初始化for(int i=1;i<=n;i++)match[i].clear();for(int i=1;i<=n;i++)//建邊for(int j=n+1;j<=n+m;j++){if(d[i][j]<=x)maze[j-n][i]=true;}for(int i=1;i<=m;i++)//跑匈牙利{memset(vis,false,sizeof(vis));if(!dfs(i))return false;}return true; }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);while(scanf("%d%d%d",&n,&m,&limit)!=EOF){for(int i=1;i<=n+m;i++)for(int j=1;j<=n+m;j++){scanf("%d",&d[i][j]);if(!d[i][j])d[i][j]=inf;}for(int k=1;k<=n+m;k++)//floyd for(int i=1;i<=n+m;i++)for(int j=1;j<=n+m;j++)if(d[i][j]>d[i][k]+d[k][j])d[i][j]=d[i][k]+d[k][j];int l=0,r=inf;int ans;while(l<=r)//二分答案:最遠距離{int mid=l+r>>1;if(check(mid)){ans=mid;r=mid-1;}elsel=mid+1;}printf("%d\n",ans);}return 0; }

?

總結

以上是生活随笔為你收集整理的POJ - 2112 Optimal Milking(二分+二分图最大匹配-多重匹配(修改匈牙利实现)+Floyd求最短路)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。