FZU 1202 信与信封问题

大意: x,y表示信x不会再信封y中,那么有多少匹配能唯一匹配可能。

思路:就是判断匹配线是不是关键匹配。(类似关键点的判断)。只不过还需要一个cro[],来存储当前数组下标和那个点匹配的(下标为信,数值为信封的编号)。


#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#define inf 0x3f3f3f3f
using namespace std;
int Map[600][600],cropath[600],cro[600];
bool use[600];
int n;
int DFS(int v)
{
    int i;
    for(i=1;i<=n;i++){
        if(!use[i]&&!Map[v][i]){
            use[i]=true;
            if(cropath[i]==-1||DFS(cropath[i])){
                cropath[i]=v;
                cro[v] = i;
                return 1;
            }
        }
    }
    return 0;
}


int main()
{
    int i,j,k;
    while(~scanf("%d",&n)){
        for(i = 1;i <= n ;++ i){
            for(j = 1;j <= n;++ j){
                Map[i][j] = 0;
            }
        }
        int a,b;

        while(~scanf("%d%d",&a,&b)){
            if(a==0&&b==0) break;
            Map[a][b] = 1;
        }

        int ans = 0;
        memset(cro,-1,sizeof(cro));
        memset(cropath,-1,sizeof(cropath));

        for(i = 1;i <= n;++ i){
            memset(use,false,sizeof(use));
            if(DFS(i)){
                ans++;
            }
        }
// for(i = 1;i <= n;++ i){
// printf("%d %d\n",i,cropath[i]);
// }
        if(ans!=n){
            printf("none\n\n");continue;
        }

        int cnt = 0;
        for(i = 1;i <= n;++ i){
            int tmp = cro[i];
            cropath[tmp] =  -1;
            Map[i][tmp] = 1;
            memset(use,false,sizeof(use));
            if(!DFS(i)){
                cropath[tmp] = i;
                cnt++;
                printf("%d %d\n",i,cro[i]);
            }
            Map[i][tmp] = 0;
        }
        if(!cnt){
            puts("none");
        }
        puts("");
    }
    return 0;
}

你可能感兴趣的:(二分图)