http://acm.fzu.edu.cn/problem.php?pid=1202

二分图最大匹配,问哪些边是必要的,O(n^3)的方法

删边的时候把连接关系也要删掉,如果在此基础上无法找到增广路,加入答案,恢复连接关系,如果能找到,连接关系不用恢复(因为要n对匹配,这组匹配新的了剩下的要留给别的组)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
int T,M[105][105],n,linkx[105],linky[105],vis[105],a[105],b[105] ;
int find(int s)
{
    for(int i=1 ;i<=n ;i++)
    {
        if(M[s][i])
        {
            if(vis[i]==T)continue ;
            vis[i]=T ;
            if(!linky[i] || find(linky[i]))
            {
                linky[i]=s ;
                linkx[s]=i ;
                return 1 ;
            }
        }
    }
    return 0 ;
}
int max_match()
{
    int ans=0 ;
    memset(linkx,0,sizeof(linkx)) ;
    memset(linky,0,sizeof(linky)) ;
    memset(vis,0,sizeof(vis)) ;
    for(int i=1 ;i<=n ;i++)
    {
        T=i ;
        ans+=find(i);
    }
    return ans;
}
struct node
{
    int first,second ;
}ans[105] ;
int cmp(node aa,node bb) 
{
    if(aa.first==bb.first)return aa.second<bb.second ;
    return aa.first<bb.first ;
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0 ;i<105 ;i++)
            for(int j=0 ;j<105 ;j++)
                M[i][j]=1 ;
        while(1)
        {
            int xx,yy ;
            scanf("%d%d",&xx,&yy) ;
            if(!xx && !yy)break ;
            M[xx][yy]=0 ;
        }
        int res=max_match() ;
        if(res!=n)
        {
            puts("none") ;
            putchar('\n') ;
            continue ;
        }
           int st=0 ;
           memset(vis,0,sizeof(vis)) ;
           for(int i=1 ;i<=n ;i++)
        {
            T=i ;
            int temp=linkx[i] ;
            M[i][temp]=0 ;
            linkx[i]=0 ;linky[temp]=0 ;
            if(!find(i))
            {
                ans[st].first=i ;
                ans[st++].second=temp ;
                linkx[i]=temp ;
                linky[temp]=i ;
            }
            M[i][temp]=1 ;
        }
        if(st)
        {
            sort(ans,ans+st,cmp) ;
            for(int i=0 ;i<st ;i++)
                printf("%d %d\n",ans[i].first,ans[i].second) ;
        }
        else puts("none") ;
        putchar('\n') ;
    }
    return 0 ;
}
View Code