FZU 1202

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

 

你可能感兴趣的:(FZU 1202)