bzoj1116 [POI2008] CLO 并查集

 [POI2008]CLO

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 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

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 }

 

posted @ 2018-04-14 19:52  Kaiser-  阅读(141)  评论(0编辑  收藏  举报