• 1143: [CTSC2008]祭祀river(最长反链)


    1143: [CTSC2008]祭祀river

    题目链接https://www.lydsy.com/JudgeOnline/problem.php?id=1143

    Description:

      在遥远的东方,有一个神秘的民族,自称Y族。他们世代居住在水面上,奉龙王为神。每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动。我们可以把Y族居住地水系看成一个由岔口和河道组成的网络。每条河道连接着两个岔口,并且水在河道内按照一个固定的方向流动。显然,水系中不会有环流(下图描述一个环流的例子)。

     

      由于人数众多的原因,Y族的祭祀活动会在多个岔口上同时举行。出于对龙王的尊重,这些祭祀地点的选择必
    须非常慎重。准确地说,Y族人认为,如果水流可以从一个祭祀点流到另外一个祭祀点,那么祭祀就会失去它神圣
    的意义。族长希望在保持祭祀神圣性的基础上,选择尽可能多的祭祀的地点。
     
    Input:
    第一行包含两个用空格隔开的整数N、M,分别表示岔口和河道的数目,岔口从1到N编号。接下来M行,每行包含两个用空格隔开的整数u、v,描述一条连接岔口u和岔口v的河道,水流方向为自u向v。
    N≤100M≤1000
     
    Output:
    第一行包含一个整数K,表示最多能选取的祭祀点的个数。
     
    Sample Input:
    4 4
    1 2
    3 4
    3 2
    4 2
    Sample Output:
    2
     
    题解:
    最长反链模板题。
    链是一个点的集合,一条链上的任意两点u,v,要么u可以到v,要么v可以到u;
    反链也是一个点的集合,但反链上的点是孤立的,不存在一对点u,v,满足在链上的情况。
    然后有个定理就是最长反链=最小链覆盖。
    这里最小链覆盖可以看作可以有交叉点的最小路径覆盖,然后就直接求就好了~具体方法是先floyd传递闭包,然后跑二分图最大匹配,n-最大匹配数  即为答案。
    代码如下:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
     
    const int N = 205 ;
    int Map[N][N],check[N*2],match[N*2],Link[N][N*2];
    int n,m,ans;
     
    inline int dfs(int x){
        for(int i=n+1;i<=2*n;i++){
            if(Link[x][i] && !check[i]){
                check[i]=1;
                if(!match[i] || dfs(match[i])){
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
     
    int main(){
        scanf("%d%d",&n,&m);
        ans=0;
        for(int i=1,x,y;i<=m;i++){
            scanf("%d%d",&x,&y);
            Map[x][y]=1;
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                if(Map[i][k])
                for(int j=1;j<=n;j++){
                    if(Map[k][j]) Map[i][j]=1;
                }
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(Map[i][j]) Link[i][j+n]=1;
        for(int i=1;i<=n;i++){
            memset(check,0,sizeof(check));
            if(dfs(i)) ans++;
        }
        printf("%d
    ",n-ans);
        return 0;
    }
  • 相关阅读:
    mysql 8.0.18 mgr节点状态长时间处于RECOVERING 状态
    mgr安装 加入第二个节点报错-[ERROR] [MY-011526] [Repl] Plugin group_replication reported: 'This member has more executed transactions than those present in the grou
    mgr安装-启动主节点报错-[ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Unable to announce tcp port
    sqlserver维护计划无法删除处理
    ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
    keepalived-2.0.15 编译安装报错
    论自由与素质
    乘法表
    python函数和方法
    python三引号的用法
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10398529.html
Copyright © 2020-2023  润新知