[CTSC2008] Sacrifice (bipartite graph matching)

Without SPJ obviously do not need the program output. Output scheme need not do well, first side extension (as will flow down), and then find the maximum independent set, maximum independent set point = n- minimum coverage, as it is a maximum independent set of complement. How to find the minimum point of covering it? After all, I wrote the maximum weight closure sub-graphs: http://www.51nod.com/Challenge/Problem.html#!#problemId=1325 , but I did not write this solution to a problem. But here overkill by network flow, Hungary directly ask the longest match to the reverse strand.

Then the next two questions can do so, the first question is obviously a direct dfs can. Point in fact, I quite ingenious approach, the enumeration to consider deleting it can reach the point / reach it, and then ask again seek answers. If the answer is found then ans-1, is the correct answer.

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int n,m,idx,bel[N];
bool a[N][N],has[N],vis[N],ban[N],s[N],t[N];
bool find(int u)
{
    if(ban[u])return 0;
    for(int i=1;i<=n;i++)
    if(!vis[i]&&a[u][i]&&!ban[i])
    {
        vis[i]=1;
        if(!bel[i]||find(bel[i])){has[u]=1,bel[i]=u;return 1;}
    }
    return 0;
}
void dfs(int u)
{
    if(s[u])return;
    s[u]=1;
    for(int i=1;i<=n;i++)if(a[u][i]&&!t[i])t[i]=1,dfs(bel[i]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<=m;i++)scanf("%d%d",&x,&y),a[x][y]=1;
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    a[i][j]=a[i][j]||a[i][k]&&a[k][j];
    int ans=n;
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof vis);
        if(find(i))ans--;
    }
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)if(!has[i])dfs(i);
    for(int i=1;i<=n;i++)printf("%d",s[i]&&!t[i]);
    puts("");
    for(int k=1;k<=n;k++)
    {
        memset(bel,0,sizeof bel);
        memset(has,0,sizeof has);
        memset(ban,0,sizeof ban);
        int tmp=0;
        for(int i=1;i<=n;i++)if(a[i][k]||a[k][i]||i==k)ban[i]=1;else tmp++;
        for(int i=1;i<=n;i++)
        {
            memset(vis,0,sizeof vis);
            if(find(i))tmp--;
        }
        printf("%d",tmp==ans-1);
    }
}
View Code

 

Guess you like

Origin www.cnblogs.com/hfctf0210/p/10991133.html