BZOJ1143 祭祀river [二分圖最大匹配]

1143: [CTSC2008]祭祀river

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2991  Solved: 1528
[Submit][Status][Discuss]

Description

  在遙遠的東方,有一個神祕的民族,自稱Y族。他們世代居住在水面上,奉龍王爲神。每逢重大慶典, Y族都

會在水面上舉辦盛大的祭祀活動。我們可以把Y族居住地水系看成一個由岔口和河道組成的網絡。每條河道連接着
兩個岔口,並且水在河道內按照一個固定的方向流動。顯然,水系中不會有環流(下圖描述一個環流的例子)。

 

  由於人數衆多的原因,Y族的祭祀活動會在多個岔口上同時舉行。出於對龍王的尊重,這些祭祀地點的選擇必
須非常慎重。準確地說,Y族人認爲,如果水流可以從一個祭祀點流到另外一個祭祀點,那麼祭祀就會失去它神聖
的意義。族長希望在保持祭祀神聖性的基礎上,選擇儘可能多的祭祀的地點。

Input

  第一行包含兩個用空格隔開的整數N、M,分別表示岔口和河道的數目,岔口從1到N編號。接下來M行,每行包

含兩個用空格隔開的整數u、v,描述一條連接岔口u和岔口v的河道,水流方向爲自u向v。 N ≤ 100 M ≤ 1 000

Output

  第一行包含一個整數K,表示最多能選取的祭祀點的個數。

Sample Input

4 4
1 2
3 4
3 2
4 2

Sample Output

2

【樣例說明】
在樣例給出的水系中,不存在一種方法能夠選擇三個或者三個以上的祭祀點。包含兩個祭祀點的測試點的方案有兩種:
選擇岔口1與岔口3(如樣例輸出第二行),選擇岔口1與岔口4。
水流可以從任意岔口流至岔口2。如果在岔口2建立祭祀點,那麼任意其他岔口都不能建立祭祀點
但是在最優的一種祭祀點的選取方案中我們可以建立兩個祭祀點,所以岔口2不能建立祭祀點。對於其他岔口
至少存在一個最優方案選擇該岔口爲祭祀點,所以輸出爲1011。

HINT

Source

code

二分圖最大匹配水水,被迫複習圖論。

#include<bits/stdc++.h>
using namespace std;
inline void read(int &res){
    static char ch;int flag=1;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
const int N = 1000100;
int n,tot,m,vis[N],tim,ans,num[N];
int mp[200][200];
bool find(int x){
    for(register int i=1;i<=n;++i){
        if(mp[x][i]&&vis[i]!=tim){
            vis[i]=tim;
            if(!num[i]||find(num[i])){
                num[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    read(n);read(m);
    for(register int x,y,i=1;i<=m;i++){
        read(x),read(y);
        mp[x][y]=1;
    }
    for(register int i,j,k=1;k<=n;k++)
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                mp[i][j]|=mp[i][k]&mp[k][j];
    for(register int i=1;i<=n;i++){
        ++tim;
        if(find(i))ans++;
    }
    printf("%d\n",n-ans);
    return 0;
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章