假设有10个驾驶员,如图中的V1,V2,…,V10就代表达10个驾驶员,其中V1,V2,V3,V4,V5是正驾驶员,V6,V7,V8,V9,V10是副驾驶员。
如果一个正驾驶员和一个副驾驶员可以同机飞行,就在代表他们两个之间连一条线,两个人不能同机飞行,就不连。例如V1和V7可以同机飞行,而V1和V8就不行。
请搭配飞行员,使出航的飞机最多。注意:因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行.
二分最大匹配版
#include <iostream> #include <algorithm> #include <vector> #include <queue> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100 + 5; vector<int> G[maxn]; int link[maxn]; bool used[maxn]; int n,m; void Init() { for(int i = 0;i < maxn;++i) G[i].clear(); } void AddEdge(int from,int to) { G[from].push_back(to); } bool dfs(int u) { for(int i = 0;i < (int)G[u].size();++i){ int v = G[u][i]; if(!used[v]){ used[v] = true; if(link[v]==-1||dfs(link[v])){ link[v] = u; //printf("%d ---> %d\n",u,v); return true; } } } return false; } int Find() { int res = 0; memset(link,-1,sizeof(link)); for(int i = 1;i <= n;++i){ memset(used,false,sizeof(used)); if(dfs(i))res++; } return res; } int main() { while(~scanf("%d%d",&n,&m)) { int x,y; Init(); while(scanf("%d%d",&x,&y),(x!=-1&&y!=-1)){ AddEdge(x,y); } int res = Find(); if(!res) puts("No Solution!"); else{ printf("%d\n",res); for(int i = n+1;i <= m;++i){ if(link[i]!=-1) printf("%d %d\n",link[i],i); } } } return 0; }
网络流最大流
#include <iostream> #include <vector> #include <queue> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100+5; const int INF = 200; struct Edge{ int from,to,cap,flow; }; vector<Edge> edges; vector<int> G[maxn]; int d[maxn],cur[maxn]; bool vst[maxn]; int n,m,s,t; void Init() { for(int i = 0;i < maxn;++i) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back((Edge){from,to,cap,0}); edges.push_back((Edge){to,from,0,0}); int sz = edges.size(); G[from].push_back(sz-2); G[to].push_back(sz-1); } //构造层次图 bool BFS() { memset(vst,false,sizeof(vst)); queue<int> Q; Q.push(s); d[s] = 0; vst[s] = true; while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i = 0;i < (int)G[u].size();++i){ Edge& e = edges[G[u][i]]; if(!vst[e.to]&&e.cap > e.flow){ d[e.to] = d[u]+1; vst[e.to] = true; Q.push(e.to); } } } return vst[t]; } //增广 int DFS(int u,int a) { if(u==t||a==0) return a; int f,flow = 0; for(int& i = cur[u];i < (int)G[u].size();++i){ Edge& e = edges[G[u][i]]; if(d[e.to]==d[u]+1&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow += f; edges[G[u][i]^1].flow -= f; flow += f; a -= f; if(a==0)break; } } return flow; } int Maxflow() { int flow = 0; while(BFS()){ memset(cur,0,sizeof(cur)); flow += DFS(s,INF); } return flow; } int main() { while(~scanf("%d%d",&n,&m)){ Init(); int x,y; while(scanf("%d%d",&x,&y),(x!=-1&&y!=-1)){ AddEdge(x,y,1); // AddEdge(y,x,1); } s = 0,t = m+1; for(int i = 1;i <= n;++i)AddEdge(s,i,1); for(int i = n+1;i <= m;++i)AddEdge(i,t,1); int res = Maxflow(); if(res<=0) puts("No Solution!"); else{ printf("%d\n",res); int sz = edges.size(); for(int i = 0;i < sz;i += 2){ Edge& e = edges[i]; if(e.flow == 1&&e.from!=s&&e.to!=t) printf("%d %d\n",e.from,e.to); } } } return 0; }