洛谷P2756 飛行員配對方案問題(二分圖匹配)
阿新 • • 發佈:2018-08-18
好用 string dep 二分圖匹配 匈牙利 ini ron clu fread
傳送門
一個基礎的二分圖匹配(雖然今天才學會)
因為不會匈牙利算法只好用網絡流做
先新建一個超級源和超級匯,源往所有左邊的點連邊,所有右邊的點往匯連邊
然後跑一邊最大流就好了
順便記錄一下匹配到誰就好了
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #define inf 0x3f3f3f3f 8 usingnamespace std; 9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 10 char buf[1<<21],*p1=buf,*p2=buf; 11 inline int read(){ 12 #define num ch-‘0‘ 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch==‘-‘)&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 char sr[1<<21],z[20];int C=-1,Z; 22 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 23 inline void print(int x,char ch){ 24 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 25 while(z[++Z]=x%10+48,x/=10); 26 while(sr[++C]=z[Z],--Z);sr[++C]=ch; 27 } 28 const int N=205,M=80505; 29 int n,m,e,u,v,maxflow,dep[N],mac[N]; 30 int head[N],Next[M],ver[M],edge[M]; 31 int tot=1,cur[N],s,t; 32 queue<int> q; 33 inline void add(int u,int v,int e){ 34 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 35 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0; 36 } 37 bool bfs(){ 38 memset(dep,-1,sizeof(dep)); 39 for(int i=0;i<=n+1;++i) cur[i]=head[i]; 40 dep[s]=0,q.push(s); 41 while(!q.empty()){ 42 int u=q.front();q.pop(); 43 for(int i=head[u];i;i=Next[i]){ 44 int v=ver[i]; 45 if(dep[v]<0&&edge[i]) 46 dep[v]=dep[u]+1,q.push(v); 47 } 48 } 49 return ~dep[t]; 50 } 51 int dfs(int u,int limit){ 52 if(!limit||u==t) return limit; 53 int flow=0,f; 54 for(int i=cur[u];i;i=Next[i]){ 55 cur[u]=i;int v=ver[i]; 56 if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){ 57 flow+=f,limit-=f; 58 edge[i]-=f,edge[i^1]+=f,mac[u]=v; 59 if(!limit) break; 60 } 61 } 62 return flow; 63 } 64 inline void dinic(){ 65 while(bfs()) maxflow+=dfs(s,inf); 66 } 67 int main(){ 68 m=read(),n=read(),s=0,t=n+1; 69 while(~(u=read())&&~(v=read())){ 70 add(u,v,inf); 71 } 72 for(int i=1;i<=m;++i) add(s,i,1); 73 for(int i=m+1;i<=n;++i) add(i,t,1); 74 dinic(); 75 print(maxflow,10); 76 for(int i=1;i<=m;++i) 77 if(mac[i]&&mac[i]!=t) 78 print(i,32),print(mac[i],10); 79 Ot(); 80 return 0; 81 }
洛谷P2756 飛行員配對方案問題(二分圖匹配)