zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法
    Apple开发者账号更改公司名称
    iOS端实现节日换肤
    那些惊艳了我的第三方插件收集
    【iOS】Mapkit的使用:地图显示、定位、大头针、气泡等
    iOS 10中如何搭建一个语音转文字框架
    哈夫曼树
    多叉树的建立以及其他的一些操作
    决策树(2)
    决策树算法(1)含java源代码
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10398529.html
Copyright © 2011-2022 走看看