【题解】座位安排

题目链接

题目大意就是,每个点连着两条边,就是人喜欢做的两个位置,求所有座位匹配上的最大匹配

这里,我们开一个二维的就好,表示两列的座位是否匹配上,返回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;
}

 

posted @ 2019-07-27 19:55  Refined_heart  阅读(179)  评论(0编辑  收藏  举报