BZOJ 3108: [cqoi2013]图的逆变换
3108: [cqoi2013]图的逆变换
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 627 Solved: 415
[Submit][Status][Discuss]
Description
给一个n结点m条边的有向图D,可以这样构造图E:给D的每条边u->v,在E中建立一个点uv,然后对于D中的两条边u->v和v->w,在E中从uv向vw连一条有向边。E中不含有其他点和边。
输入E,你的任务是判断是否存在相应的D。注意,D可以有重边和自环。
Input
第一行包含测试数据个数T(T<=10)。每组数据前两行为D的边数(即E的点数)m和E的边数k(0<=m<=300)。以下k行每行两个整数x, y,表示E中有一条有向边x->y。E中的点编号为0~m-1。
Output
对于每组数据输出一行。如果存在,输出Yes,否则输出No。
Sample Input
4
2
1
0 1
5
0
4
3
0 1
2 1
2 3
3
9
0 1
0 2
1 2
1 0
2 0
2 1
0 0
1 1
2 2
2
1
0 1
5
0
4
3
0 1
2 1
2 3
3
9
0 1
0 2
1 2
1 0
2 0
2 1
0 0
1 1
2 2
Sample Output
Yes
Yes
No
Yes
Yes
No
Yes
题解:不存在的情况为:有x->y ; z->y ; 则他们的终点相同,则在有 x->k 却没有 z->k(或则有z->k却没有x->k)这种情况是不存在的;
参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define clr(a,b) memset(a,b,sizeof a) 4 typedef long long ll; 5 const int base=310; 6 int T,m,k,u,v,mp[310][310]; 7 bool solve() 8 { 9 for(int i=1;i<=m;++i) 10 { 11 for(int j=i+1;j<=m;++j) 12 { 13 int f1=0,f2=0; 14 for(int k=1;k<=m;++k) 15 { 16 if(mp[i][k]&&mp[j][k]) f1=1; 17 if(mp[i][k]^mp[j][k]) f2=1; 18 if(f1&&f2) return false; 19 } 20 } 21 } 22 return true; 23 } 24 int main() 25 { 26 scanf("%d",&T); 27 while(T--) 28 { 29 clr(mp,0); 30 scanf("%d%d",&m,&k); 31 for(int i=1;i<=k;++i) 32 { 33 scanf("%d%d",&u,&v); 34 mp[++u][++v]=1; 35 } 36 if(solve()) printf("Yes\n"); 37 else printf("No\n"); 38 } 39 40 return 0; 41 } 42