zoukankan      html  css  js  c++  java
  • 偏序集的最大反链【二分图】

    在有向无环图中,有如下的一些定义和性质:

    链:一条链是一些点的集合,链上任意两个点x, y,满足要么 x 能到达 y ,要么 y 能到达 x 。

    反链:一条反链是一些点的集合,链上任意两个点x, y,满足 x 不能到达 y,且 y 也不能到达 x。

    又有诸如以下定理:

    一、有向无环图最小不相交路径覆盖 
    定义:用最少的不相交路径覆盖所有顶点。 
    定理:把原图中的每个点V拆成Vx和Vy,如果有一条有向边A->B,那么就加边Ax-By。这样就得到了一个二分图,最小路径覆盖=原图的节点数-新图最大匹配。 
    简单证明:一开始每个点都独立的为一条路径,总共有n条不相交路径。我们每次在二分图里加一条边就相当于把两条路径合成了一条路径,因为路径之间不能有公共点,所以加的边之间也不能有公共点,这就是匹配的定义。所以有:最小路径覆盖=原图的节点数-新图最大匹配。

    二、有向无环图最小可相交路径覆盖 
    定义:用最小的可相交路径覆盖所有顶点。 
    算法:先用floyd求出原图的传递闭包,即如果a到b有路,那么就加边a->b。然后就转化成了最小不相交路径覆盖问题。

    三、偏序集的最大反链 
    定义:偏序集中的最大独立集。 
    Dilworth定理:对于任意偏序集都有,最大独立集(最大反链)=最小链的划分(最小可相交路径覆盖). 
    通过Dilworth定理, 我们就可以把偏序集的最大独立集问题转化为最小可相交路径覆盖问题了。

    经典例题:

    BZOJ 1143祭祀river

    #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXN=105;
    int g[MAXN][MAXN];
    
    int uN,vN;
    int linker[MAXN];
    bool used[MAXN];
    bool dfs(int u)
    {
        for(int v = 0; v < vN; v++)
            if(g[u][v] && !used[v])
            {
                used[v] = true;
                if(linker[v] == -1 || dfs(linker[v]))
                {
                    linker[v] = u;
                    return true;
                }
            }
        return false;
    }
    int hungary()
    {
        int res = 0;
        memset(linker,-1,sizeof(linker));
        for(int u = 0; u < uN; u++)
        {
            memset(used,false,sizeof(used));
            if(dfs(u))res++;
        }
        return res;
    }
    
    int main()
    {
        int n,m;
        while (~scanf("%d%d",&n,&m))
        {
            memset(g,0,sizeof(g));
            for (int i=1; i<=m; i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                g[u-1][v-1]=1;
            }
            for (int k=0; k<n; k++)
                for (int i=0; i<n; i++)
                    for (int j=0; j<n; j++)
                        if (g[i][k] && g[k][j]) g[i][j]=1;
            uN=vN=n;
            printf("%d
    ",n-hungary());
        }
        return 0;
    }
  • 相关阅读:
    201521123051 《Java程序设计》 第二周学习总结
    201521123001《Java程序设计》第11周学习总结
    201521123001《Java程序设计》第12周学习总结
    201521123001《Java程序设计》第11周学习总结
    201521123001《Java程序设计》第10周学习总结
    201521123001《Java程序设计》第9周学习总结
    201521123001《Java程序设计》第8周学习总结
    201521123001《Java程序设计》第7周学习总结
    201521123001《Java程序设计》第6周学习总结
    201521123001《Java程序设计》第5周学习总结
  • 原文地址:https://www.cnblogs.com/darklights/p/8000841.html
Copyright © 2011-2022 走看看