URAL 1533 Fat Hobbits

题意

构造最长反链

题解

先来回顾一下几个做法:
1. 求最长链——直接DP,然后还可能可以用二分优化
2. 求最小反链覆盖——类似拓扑排序,每次把度为0的点找出来删掉即可
3. 求最小链覆盖——即是在求路径覆盖,把每个点拆成i_0,i_1,原图i->j(注意要补全所有关系),则连i_0->j_1,
(点数-最大匹配数)即为答案。构造即为把匹配边“对回去”“连起来”
4. 求最长反链——在3.那个二分图中,求一个最小点覆盖集,则i被取出当且仅当i_0,i_1均不在这个点覆盖集中。
证明:
(1)求出的点集一定满足反链。证明:如果选出的某两个点之间有边,则不符合覆盖集定义,矛盾。
(2)i_0与i_1不可能同时在点覆盖集中。证明:若如此,则|反链|>n-|最小点覆盖|=n-|最大匹配|=|最小链覆盖|=|最长链|,矛盾。
(注意3和4需要把偏序关系补全,否则会出现问题,例如1->2->3)


然后再来回顾一下二分图求最小点覆盖
1. 求最大匹配
2. 对于左边所有的未配点,做增广,并标记(此时增广一定失败,否则就不是最大匹配了)
3. 左边所有的未标记点和右边所有的已标记点即为答案。
原因:
(1) 观察所有未匹配边,因为未配边不可能两边都是未配点(否则与最大匹配矛盾)
a. 左边是未配点,此时左边的点会被增广,右边的匹配点会被标记,由(3)会被覆盖。
b. 右边是未配点,那么左边一定是已配点,这种边不可能作为增广的最后一条边(否则增广路被找到),所以左右两边点都不会被标记,由(3)会覆盖
(2) 观察所有匹配边,要么在(3)中被标记,此时右边点被标记,要么左边的点没有标记,由(3)会被覆盖
同时,所有匹配边仅有一侧被覆盖,故此时|点覆盖集|=|最大匹配|,满足定理,故是合法最小覆盖集。

code

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cassert>
using namespace std;

const int maxn=110;

int n;

int G[maxn][maxn];

int left[maxn],right[maxn];
int S[maxn],T[maxn];
bool match(int u){
    if(S[u]) return 0;
    S[u]=1;
    for(int v=1;v<=n;++v)if(G[u][v]){
        if(T[v]) continue;
        T[v]=1;
        if(!left[v] || match(left[v])){
            left[v]=u;
            right[u]=v;
            return 1;
        }
    }
    return 0;
}

int main(){
//  freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&G[i][j]);
    for(int k=1;k<=n;++k) for(int i=1;i<=n;++i)if(G[i][k]) for(int j=1;j<=n;++j)if(G[k][j]) G[i][j]=1;
    int res=0;
    memset(left,0,sizeof left);
    memset(right,0,sizeof right);
    for(int i=1;i<=n;++i)if(!right[i]){
        memset(S,0,sizeof S);
        memset(T,0,sizeof T);
        if (match(i)) ++res;
    }
    printf("%d\n",n-res);

    memset(S,0,sizeof S);
    memset(T,0,sizeof T);
    for(int i=1;i<=n;++i)if(!right[i]) match(i);

    int res2=0;
    for(int i=1;i<=n;++i)if(!(!S[i] || T[i])){
        printf("%d%c",i,(++res2)==n-res ? '\n' : ' ');
    }

//  for(;;);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/yeziqing10/article/details/50651560