题解-[luogu]2071

题目在这里

这题可以用网络流或者匈牙利,这里用的是匈牙利算法。 这题的思路很容易想到:应为每排座位都有两个人可以做,那么我们就将每个座位代表的点的数量乘以2就行了。 还有,我们的边的数量要开点的数量的4倍,因为每个点(包括乘2后的点)最多有两条通向这个点的连边,而每次输入2个点时相当于输入了4个点(包括拓展出去的两个点)

#include<bits/stdc++.h>
using namespace std;

const int maxn=5000;

struct node{
    int next,v;
}edge[maxn<<2];
int head[maxn],tot,n,vis[maxn],match[maxn];

void add(int u,int v)
{
    edge[++tot].next=head[u];
    edge[tot].v=v;
    head[u]=tot;
}

bool dfs(int u)
{
    for(int i=head[u];i;i=edge[i].next)
    {
        int v=edge[i].v;
        if(!vis[v])
        {
            vis[v]=1;
            if(!match[v] || dfs(match[v]))
            {
                match[v]=u;return 1;
            }
        }
    }
    return 0;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n<<1;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add((a<<1)-1,i);add(a<<1,i);
        add((b<<1)-1,i);add(b<<1,i);
    }   
    int ans=0;
    for(int i=1;i<=n<<1;++i)
    {
        memset(vis,0,sizeof(vis));
        ans+=dfs(i);
    }

    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/guoyangfan_/article/details/83477746
今日推荐