题目大意就是,每个点连着两条边,就是人喜欢做的两个位置,求所有座位匹配上的最大匹配
这里,我们开一个二维的就好,表示两列的座位是否匹配上,返回01即可。
匈牙利模板题。
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int match[500000][2]; int head[500000],n,ans; int vis[500000],tot; struct node{ int nxt,to; }e[500000]; bool dfs(int x){ for(int i=head[x];i;i=e[i].nxt){ int j=e[i].to; if(vis[j])continue; vis[j]=1; if(!match[j][0]||dfs(match[j][0])){//j的第一个座位是不是已经匹配上 match[j][0]=x; return true; } if(!match[j][1]||dfs(match[j][1])){//同上 match[j][1]=x; return true; } }return false;//没有匹配 } void work(){ for(int i=1;i<=(n<<1);++i){ memset(vis,0,sizeof(vis)); ans+=dfs(i);//求最大匹配 } } inline void add(int x,int y){//临接表 e[++tot].nxt=head[x]; head[x]=tot; e[tot].to=y; } int main(){ scanf("%d",&n); for(int i=1;i<=(n<<1);++i){//2n个点 int x,y; scanf("%d%d",&x,&y); add(i,x);add(i,y);//i想做的位置连边 } work(); printf("%d\n",ans); return 0; }