BZOJ 1143: [CTSC2008]祭祀river(二分图最大点独立集)

 http://www.lydsy.com/JudgeOnline/problem.php?id=1143

题意:

 

思路:

二分图最大点独立集,首先用floyd判断一下可达情况。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int n,m,tot;
int mp[105][105],mark[105],head[105];
bool vis[105];

struct node
{
    int v,next;
}e[1005];

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

void floyd()
{
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
        mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);
}

bool match(int u)
{
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v = e[i].v;
        if(!vis[v])
        {
            vis[v] = true;
            if(mark[v]==-1 || match(mark[v]))
            {
                mark[v] = u;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    tot = 0;
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        mp[u][v] = 1;
    }
    floyd();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(mp[i][j]) addEdge(i,j);
        }
    }
    int sum = 0;
    memset(mark,-1,sizeof(mark));
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if(match(i))  sum++;
    }
    printf("%d\n",n-sum);
}

  

 

posted @ 2017-11-27 15:54  Kayden_Cheung  阅读(94)  评论(0编辑  收藏
//目录