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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配)

發(fā)布時(shí)間:2024/4/11 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接:點(diǎn)擊查看

題目大意:給出n個(gè)人和m個(gè)雨傘,t分鐘后就要下雨了,現(xiàn)在給出每個(gè)人的坐標(biāo)和速度,以及雨傘所在的坐標(biāo),每個(gè)雨傘只能容納一個(gè)人,題目問最多有多少個(gè)人能不被淋到

題目分析:二分圖最大匹配,但是對(duì)算法有要求,用匈牙利時(shí)間復(fù)雜度是O(VE),會(huì)超時(shí),用最大流雖然時(shí)間復(fù)雜度是O(sqrt(V)E),但是有N*M*2條邊,會(huì)爆內(nèi)存,所以只能選擇用HK算法,時(shí)間復(fù)雜度也是O(sqrt(V)E),空間復(fù)雜度是O(NM)

關(guān)于HK算法的大牛博客:點(diǎn)擊查看

剩下的就是模板題了,建好圖直接跑模板就好了

代碼:

#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 = 3e3+100;const int M = 3e3+100;int dx[N],dy[M],cx[N],cy[M],dis,n,m;bool vis[M],maze[N][M];bool bfs_findPath() {queue<int> q;memset(dx,-1,sizeof(dx));memset(dy,-1,sizeof(dy));// 使用BFS遍歷對(duì)圖的點(diǎn)進(jìn)行分層,從X中找出一個(gè)未匹配點(diǎn)v// (所有v)組成第一層,接下來的層都是這樣形成——每次查找// 匹配點(diǎn)(增廣路性質(zhì)),直到在Y中找到未匹配點(diǎn)才停止查找,// 對(duì)X其他未匹配點(diǎn)同樣進(jìn)行查找增廣路徑(BFS只分層不標(biāo)記// 是否匹配點(diǎn))// 找出X中的所有未匹配點(diǎn)組成BFS的第一層dis=inf;for(int i=1;i<=n;++i) {if(cx[i]==-1) {q.push(i);dx[i]=0;}}while(!q.empty()) {int u=q.front();q.pop();if(dx[u]>dis) break;// 該路徑長度大于dis,等待下一次BFS擴(kuò)充for(int v=1;v<=m;++v) {if(maze[u][v]&&dy[v]==-1) {// (u,v)之間有邊且v還沒有分層dy[v]=dx[u]+1;if(cy[v]==-1) dis=dy[v];// v是未匹配點(diǎn),停止延伸(查找),得到本次BFS的最大遍歷層次else {// v是已匹配點(diǎn),繼續(xù)延伸dx[cy[v]]=dy[v]+1;q.push(cy[v]);}}}}return dis!=inf;// 若dis為inf說明Y中沒有未匹配點(diǎn),也就是沒有增廣路徑了 }bool dfs(int u) {for(int v=1;v<=m;++v) {if(!vis[v]&&maze[u][v]&&dy[v]==dx[u]+1) {vis[v]=1;// 層次(也就是增廣路徑的長度)大于本次查找的dis// 是bfs中被break的情況,也就是還不確定是否是增廣路// 只有等再次調(diào)用bfs再判斷(每次只找最小增廣路集)if(cy[v]!=-1&&dy[v]==dis) continue;if(cy[v]==-1||dfs(cy[v])) {// 是增廣路徑,更新匹配集cy[v]=u;cx[u]=v;return true;}}}return false; }int HK() {int ans=0;memset(cx,-1,sizeof(cx));memset(cy,-1,sizeof(cy));while(bfs_findPath()) {// 有增廣路memset(vis,0,sizeof(vis));for(int i=1;i<=n;++i) {// 用DFS查找增廣路徑,增廣路徑一定從未匹配點(diǎn)開始// 如果查找到一個(gè)增廣路徑,匹配數(shù)加一if(cx[i]==-1&&dfs(i)) ++ans;}}return ans; }void init() {memset(maze,false,sizeof(maze)); }struct Node {double x,y,dis; }a[N],b[N];double distance(int x,int y) {return hypot(a[x].x-b[y].x,a[x].y-b[y].y); }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int w;cin>>w;int kase=0;while(w--){init();int time;scanf("%d",&time);scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].dis);a[i].dis*=time;}scanf("%d",&m);for(int i=1;i<=m;i++)scanf("%lf%lf",&b[i].x,&b[i].y);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(a[i].dis>=distance(i,j))maze[i][j]=true;printf("Scenario #%d:\n%d\n\n",++kase,HK());}return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。