开始看错题了囧。。。
要求选一部分边变为单向边。。并不是全都要变QAQ。
这样就比较好考虑了:
如果原图没有环,我们改变边的方向只会构造出一个类似树形结构,总会有点没有入度。而如果原图有环,我们构造一个基环外向树就好啦。。。
于是并查集维护一下:
如果当前两个点在一个联通块内,那么就在根上打一个标记。否则合并的时候如果有一个联通块有标记(证明有环)则合并后的也有标记。。最后check一下是否每个联通块的根都有标记就好啦。
#include<bits/stdc++.h>
using namespace std;
int n,m,f[100005];
bool v[100005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
int find(int i)
{
return f[i]==i?i:f[i]=find(f[i]);
}
int main()
{
n=read(); m=read();
for (int i=1;i<=n;i++) f[i]=i;
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),p=find(x),q=find(y);
if (p!=q)
{
f[p]=q;
v[q]|=v[p];
}
else v[p]=1;
}
for (int i=1;i<=n;i++)
if (!v[find(i)])
{
puts("NIE");
return 0;
}
puts("TAK");
return 0;
}