bzoj1116 [POI2008] CLO 并查集
[POI2008]CLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1218 Solved: 668
[Submit][Status][Discuss]
Description
Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 你要把其中一些road变成单向边使得:每个town都有且只有一个入度
Input
第一行输入n m.1 <= n<= 100000,1 <= m <= 200000 下面M行用于描述M条边.
Output
TAK或者NIE 常做POI的同学,应该知道这两个单词的了...
Sample Input
4 5
1 2
2 3
1 3
3 4
1 4
1 2
2 3
1 3
3 4
1 4
Sample Output
TAK
上图给出了一种连接方式.
上图给出了一种连接方式.
HINT
题解:这题是一个水题,以前做过一道很像的题目,并查集连接的方式,如果两个点已经是了,
那么根节点打上标记但是写blog的时候发现有且只有一个入度,这个我貌似没考虑啊,
只是考虑了能否满足每个点都有至少一个入度,但是过了,神奇。
1 #include<cstring> 2 #include<algorithm> 3 #include<iostream> 4 #include<cstdio> 5 #include<cmath> 6 7 #define N 100007 8 using namespace std; 9 inline int read() 10 { 11 int x=0,f=1;char ch=getchar(); 12 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 13 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 17 int n,m; 18 int fa[N]; 19 bool vis[N]; 20 21 #undef N 22 int find(int num) 23 { 24 if (fa[num]!=num) fa[num]=find(fa[num]); 25 return fa[num]; 26 } 27 int main() 28 { 29 n=read(),m=read(); 30 for (int i=1;i<=n;i++) 31 fa[i]=i; 32 for (int i=1;i<=m;i++) 33 { 34 int x=read(),y=read(); 35 x=find(x),y=find(y); 36 if (x!=y) fa[y]=x,vis[x]|=vis[y]; 37 else vis[x]=true; 38 } 39 bool flag=false; 40 for (int i=1;i<=n;i++) 41 if (fa[i]==i&&!vis[i]) flag=true; 42 if (flag) puts("NIE"); 43 else puts("TAK"); 44 }