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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P3386 【模板】二分图匹配

發布時間:2023/12/14 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3386 【模板】二分图匹配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

給定一個二分圖,結點個數分別為n,m,邊數為e,求二分圖最大匹配數

題目地址


匈牙利算法

  • 本質上是對于每個點進行dfs,并在遞歸的同時不斷找出新的增廣路.
  • 注意點:
  • 需要使用vis數組并在每次dfs前清空,防止死循環.
  • 模板里不需要加雙向邊.
  • vis并不是增廣成功才能設置,失敗不設置一定會爆棧的.
  • 在dfs的過程中累加ans會導致增廣路全部被計入.
  • Dinic算法

    • 和其他題一樣,對面的點集需要序號平移n個單位.

    匈牙利算法

    #include<cstdio> #include<iostream> #include<cstring> using namespace std; const int MAXN=10010,MAXM=1000010; struct Edge{int from,to,nxt; }e[MAXM]; int head[MAXN],edgeCnt=1; void addEdge(int u,int v){e[++edgeCnt].from=u;e[edgeCnt].to=v;e[edgeCnt].nxt=head[u];head[u]=edgeCnt; } int vis[MAXN],match[MAXN]; int dfs(int x){for(int i=head[x];i;i=e[i].nxt){int nowV=e[i].to;if(vis[nowV])continue;vis[nowV]=1;if(!match[nowV]||dfs(match[nowV])){match[nowV]=x;return 1;}}return 0; } int main(){int n,m,e;scanf("%d%d%d",&n,&m,&e);for(int i=1;i<=e;i++){int u,v;scanf("%d%d",&u,&v);if(v>m||u>n)continue;addEdge(u,v);}int ans=0;for(int i=1;i<=n;i++){memset(vis,0,sizeof(vis));if(dfs(i))ans++;}printf("%d\n",ans);return 0; }

    Dinic算法

    #include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; const int MAXN=1000010,MAXM=1000010; int s,t; struct Edge{int from,to,w,nxt; }e[MAXM]; int head[MAXN],edgeCnt=1; void addEdge(int u,int v,int w){e[++edgeCnt].from=u;e[edgeCnt].to=v;e[edgeCnt].w=w;e[edgeCnt].nxt=head[u];head[u]=edgeCnt; } int d[MAXN]; bool bfs(){memset(d,0,sizeof(d));queue<int> q;d[s]=1;q.push(s);while(!q.empty()){int nowV=q.front();q.pop();for(int i=head[nowV];i;i=e[i].nxt){int nowNode=e[i].to;if(!d[nowNode]&&e[i].w){d[nowNode]=d[nowV]+1;if(nowNode==t)return 1;q.push(nowNode);}}}return 0; } int Dinic(int x,int flow){if(x==t)return flow;int rest=flow;for(int i=head[x];i&&rest;i=e[i].nxt){int nowV=e[i].to;if(d[nowV]==d[x]+1&&e[i].w){int k=Dinic(nowV,min(rest,e[i].w));if(!k)d[nowV]=0;e[i].w-=k,e[i^1].w+=k;rest-=k;}}return flow-rest; } const int INF=2e9; int main(){int n,m,e;scanf("%d%d%d",&n,&m,&e);s=n+m+1,t=n+m+2;int u,v;for(int i=1;i<=n;i++){addEdge(s,i,1);addEdge(i,s,0);}for(int i=1;i<=e;i++){int u,v;scanf("%d%d",&u,&v);if(v>m||u>n)continue;addEdge(u,v+n,1);addEdge(v+n,u,0);//}for(int i=1;i<=m;i++){addEdge(i+n,t,1);addEdge(t,i+n,0);}int ans=0;while(bfs()){ans+=Dinic(s,2e9);}cout<<ans<<endl;return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的P3386 【模板】二分图匹配的全部內容,希望文章能夠幫你解決所遇到的問題。

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