P3386 【模板】二分图匹配
生活随笔
收集整理的這篇文章主要介紹了
P3386 【模板】二分图匹配
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
給定一個二分圖,結點個數分別為n,m,邊數為e,求二分圖最大匹配數
題目地址
匈牙利算法
- 本質上是對于每個點進行dfs,并在遞歸的同時不斷找出新的增廣路.
- 注意點:
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 【模板】二分图匹配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rk3399 usbwifi Mirac
- 下一篇: Datawhale组队学习-NLP新闻文