题意
给一个n结点m条边的有向图D,可以这样构造图E:给D的每条边u->v,在E中建立一个点uv,然后对于D中的两条边u->v和v->w,在E中从uv向vw连一条有向边。E中不含有其他点和边。
输入E,你的任务是判断是否存在相应的D。注意,D可以有重边和自环。
第一行包含测试数据个数T(T<=10)。每组数据前两行为D的边数(即E的点数)m和E的边数k(0<=m<=300)。以下k行每行两个整数x, y,表示E中有一条有向边x->y。E中的点编号为0~m-1。
分析
无聊题,想那么多干嘛,直接模拟就好了。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=605;
int n,m,f[N],cnt,last[N];
struct edge{int to,next;}e[N];
bool ma[305][305];
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;
}
int find(int x)
{
if (f[x]==x) return x;
else return f[x]=find(f[x]);
}
void addedge(int u,int v)
{
e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;
}
int main()
{
int T=read();
while (T--)
{
n=read();m=read();
for (int i=1;i<=n*2;i++) f[i]=i;
memset(ma,0,sizeof(ma));
for (int i=1;i<=m;i++)
{
int x=read()+1,y=read()+1;
f[find(x*2)]=find(y*2-1);
ma[x][y]=1;
}
cnt=0;memset(last,0,sizeof(last));
for (int i=1;i<=n;i++) addedge(find(i*2-1),i);
int flag=0;
for (int i=1;i<=n;i++)
for (int j=last[find(i*2)];j;j=e[j].next)
if (!ma[i][e[j].to]) flag=1;
if (!flag) puts("Yes");
else puts("No");
}
return 0;
}