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
上图给出了一种连接方式.
上图给出了一种连接方式.
这题跟scoi游戏差不多
不同的是在联通块中当且仅当有>=n条边存在时存在一组解
因为每一条有向边最多贡献一个入度,所以有环才有解。无向边不贡献入度,所以当一个联通块中已经有环时再加无向边是可行的
换句话说出现无解的情况只可能是有点得不到一个入度,而不会出现入读大于1的情况
这样一来判是否所有联通块都有环只要找联通块的根,而不是一个一个判过去(我就是这里又wa又t一时爽)
具体看代码吧
#include<cstdio> #define maxn 100010 int n,m,x,y,fx,fy; int fa[maxn]; bool mark[maxn]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline int gfa(int x) {return fa[x]==x?x:fa[x]=gfa(fa[x]);} int main() { n=read();m=read(); for (int i=1;i<=n;i++)fa[i]=i; for (int i=1;i<=m;i++) { x=read();y=read(); fx=gfa(x);fy=gfa(y); if (fx==fy) { mark[fx]=1; continue; } fa[fy]=fx; mark[fx]=mark[fy]|mark[fx]; } for (int i=1;i<=n;i++) if (!mark[gfa(i)]) { printf("NIE"); return 0; } printf("TAK"); return 0; }
——by zhber,转载请注明来源