题目链接:http://www.51nod.com/onlineJudge/problemList.html#!groupId=1
求最大配对人数,入门题。
一个一个去配对,如果当前的人所想配对的皇家飞行员没有人配对,直接进行匹配,
否则的话,我们看看与这个皇家飞行员配对的那个外国飞行员能不能和别人在匹配。
如果可以,则当前二人还是可以匹配的。
AC代码:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
const int maxn = 1000;
vector<int>node[maxn];
bool vis[maxn];
int match[maxn];
bool dfs(int x)
{
for(int i = 0; i < node[x].size(); i++) ///与x有关系的皇家飞行员
{
int y = node[x][i];
if(vis[y]==false)
{
vis[y]=true;
///如果y没有和别人配对,或已经与y配对的人可以找到其他的伴侣,就可以与y配对。
if(match[y]==-1 || dfs(match[y]))
{
match[y] = x;
match[x] = y;
return true;
}
}
}
return false;
}
int main()
{
int m,n;
while(~scanf("%d%d",&m,&n)) ///m是外籍飞行员的数量,n是皇家飞行员的数目。
{
int foreign,home; ///外籍飞行员编号,国内飞行员编号
memset(node,0,sizeof(node));
while(1)
{
scanf("%d%d",&foreign,&home);
if(foreign == -1 && home== -1) break;
node[foreign].push_back(home);
node[home].push_back(foreign);
}
int ans = 0;
///对m个外籍飞行员进行匹配
memset(match,-1,sizeof(match));
for(int i = 1; i <= m; i++)
{
memset(vis,false,sizeof(vis));
if(dfs(i))
ans++;
}
if(ans == 0)
printf("No Solution\n");
else
printf("%d\n",ans);
}
return 0;
}
学了网络流后,知道网络流可以求解二分图最大匹配数,所以用dinic算法写了一下。其求解出
的最大流就是二分图的最大匹配数。
AC代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int maxn = 300;
const int INF = 0x3f3f3f3f;
int cap[maxn][maxn];
int maxFlow,minFlow,minFlowNode;
int level[maxn];
int vis[maxn];
int m,n,S,D;
///m是外籍飞行员的数量,n是英国皇家飞行员的数量
bool bfs()
{
memset(level,-1,sizeof(level));
queue<int>qu;
level[S] = 0;
qu.push(S);
int u;
while(!qu.empty())
{
u = qu.front();
qu.pop();
for(int i = 0; i <= m+n+1; i++)
{
if(level[i]==-1 && cap[u][i]>0)
{
level[i] = level[u] + 1;
if(i == D)
return true;
qu.push(i);
}
}
}
return false;
}
void dfs()
{
memset(vis,0,sizeof(vis));
deque<int>qu;
vis[S] = 1;
qu.push_back(S);
int i,cur,u,v;
while(!qu.empty())
{
cur = qu.back();
if(cur == D)
{
minFlow = INF+1;
minFlowNode = S;
for(i = 1; i < qu.size(); i++)
{
u = qu[i-1];
v = qu[i];
if(cap[u][v]>0 && cap[u][v]<minFlow)
{
minFlow = cap[u][v];
minFlowNode = u;
}
}
maxFlow += minFlow;
for(i = 1; i < qu.size(); i++)
{
u = qu[i-1];
v = qu[i];
cap[u][v] -= minFlow;
cap[v][u] += minFlow;
}
while(!qu.empty() && qu.back() != minFlowNode)
{
vis[qu.back()] = 0;
qu.pop_back();
}
}
else
{
for(i = 0; i <= m+n+1; i++)
{
if(vis[i]==0 && cap[cur][i]>0 && level[i] == level[cur]+1)
{
vis[i] = 1;
qu.push_back(i);
break;
}
}
if(i > m+n+1)
qu.pop_back();
}
}
}
void dinic()
{
maxFlow = 0;
while(bfs())
{
dfs();
}
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
memset(cap,0,sizeof(cap));
int home,foreigh;
while(true)
{
scanf("%d%d",&foreigh,&home);
if(foreigh == -1 && home == -1)
break;
cap[home][foreigh] = INF;
}
S = 0;
D = m+n+1;
for(int i = m+1; i <= m+n; i++)
cap[S][i] = 1;
for(int i = 1; i <= m; i++)
cap[i][D] = 1;
dinic();
if(maxFlow == 0)
printf("No Solution!\n");
else
printf("%d\n",maxFlow);
}
return 0;
}