【图论】【二分图匹配】[POJ 3692]Kindergarten

来源:互联网 发布:ff14暗战数据 编辑:程序博客网 时间:2024/05/13 11:53

首先我们要求的是一个完全图,那么因为男生之间互相认识,女生之间互相认识,那么我们只考虑男生和女生认识的情况,我们要选择一个大家都互相认识的出来,那么做当前图的补图可以发现如果两个点之间有直接关系,那么这两个点一定是互相不认识的,如果没有,那么一定是认识的,所以选出的点在当前图中不能互相接触,那么求得就是二分图的最大独立集那么ans=|V|ans

#include <cstdio>#include <cstring>#include <algorithm>//#include <conio.h>#include <iostream>#include <vector>using namespace std;const int MAXN = 400;bool vis[MAXN+10];int con[MAXN+10];int endcnt;int n, m, k, Tcnt;struct node{     int v;    node *next;}Edges[MAXN * MAXN * 2+10], *adj[MAXN+10], *ecnt=Edges;void addedge(int u, int v){    ++ecnt;    ecnt->v = v;    ecnt->next = adj[u];    adj[u] = ecnt;}bool dfs(int u){    for(node *p=adj[u];p;p=p->next){        if(!vis[p->v]){            vis[p->v] = true;            if(con[p->v]==-1 || dfs(con[p->v])){                con[u] = p->v;                con[p->v] = u;                return true;            }        }    }    return false;}void work(){    int ret = 0;    memset(con, -1, sizeof con);    for(int i=endcnt;i>=1;i--) if(con[i] == -1){        memset(vis, 0, sizeof vis);        ret += dfs(i);        //if(ret == n) break;    }    printf("Case %d: %d\n", ++Tcnt, n+m-ret);}bool Map[MAXN+5][MAXN+5];bool read(){    memset(Map, 0, sizeof Map);    int t1, t2;    scanf("%d%d%d", &n, &m, &k);    if(!n && !m && !k) return false;    for(int i=1;i<=k;i++){        scanf("%d%d", &t1, &t2);        Map[t1][t2] = true;    }    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(!Map[i][j]){                addedge(i, j+n);                addedge(j+n, i);            }        }    }    endcnt=n;    return true;}int main(){    while(read()){        work();        memset(adj, 0, sizeof adj);        ecnt=Edges;    }    return 0;}
0 0
原创粉丝点击