算法
二分图匹配板子。
细节见代码。
代码
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define re register
using namespace std;
inline int read() //快读
{
int X=0,w=1; char ch=getchar();
while (ch<'0'||ch>'9') { if (ch=='-') w=-1; ch=getchar(); }
while (ch>='0'&&ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X*w;
}
bool vis[210];
int n,m,k;
int ans=0;
int link[210],head[210],cnt=0; //link[i]表示与第i个人匹配的人
struct Edge //邻接表
{
int v,nxt;
Edge() { this->v=this->nxt=0; }
}e[40010];
inline void addEdge(int u,int v) //加边
{
cnt++;
e[cnt].v=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
inline bool Hungary(int u) //匈牙利算法
{
for (re int i=head[u];i;i=e[i].nxt) { //扫描所有人
int v=e[i].v;
if (!vis[v]) { //没有访问过
vis[v]=true; //标记
if (!link[v]||Hungary(link[v])) { //能匹配
link[v]=u; //匹配
return true; //匹配成功
}
}
}
return false; //匹配失败
}
int main()
{
n=read(); m=read();
int u=0,v=0;
while (u!=-1&&v!=-1) { //输入、建图
u=read(); v=read();
if (u==-1&&v==-1) break;
addEdge(u,v);
}
for (re int i=1;i<=n;i++) { //匹配每个人
memset(vis,0,sizeof(vis));
if (Hungary(i)) ans++;
}
if (ans==0) printf("No Solution!\n"); //没有人被匹配就无解
else {
printf("%d\n",ans); //输出匹配数
for (re int i=1;i<=m;i++)
if (link[i]) printf("%d %d\n",link[i],i); //输出匹配对
}
return 0;
}