bzoj 3108 //3108: [cqoi2013]图的逆变换 //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=3108
更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录
bzoj 3108
1184 kb | 420 ms | C++/Edit | 828 B |
洛谷281ms / 1.15MB / 584B C++
//3108: [cqoi2013]图的逆变换
//在线测评地址https://www.luogu.org/problem/P4575
//第一遍读题,觉得样例1有问题,又对样例1,自底向上读,总算明白了,没有问题.
//突然发现题意不明.重心放在弄懂No这组数据上.
//突破未果.此文https://wenku.baidu.com/view/ce51a6d7d0f34693daef5ef7ba0d4a7303766c6d.html思路不错,摘抄如下:
//再读题,发现关键的地方在这"对于D中的两条边u->v和v->w,在E中从uv向vw连一条有向边"
//怎么就没读出来呢.
//此文https://blog.csdn.net/Ripped/article/details/70260146思路不错,摘抄如下
/*
假设有四个点i、j、k、t,如果i和j都向k有一条边,并且i和j中有且仅有一个点向t连边,则这个图是不合法的。
为什么呢?令i=ac(按照定义来),j=bc,k=cd,t=ce然后有:
i->k表示a->c->d
j->k表示b->c->d
如果i->t,则有a->c->e,得到b->c->e,即j->t。
反之j->t,则有b->c->e,得到a->c->e,即i->t。
也就是说i和j要么一起连到t要么一起不连到t,直连一个就是不合法的。
*/
//上述思路,构图如下
由E图
i->k
j->k
i->t
可推得D图
由D图
可推得E图
i->k
j->k
i->t
j->t
前后2幅E图数据显然矛盾.2019-10-6 16:19
//样例中第3组数据构图如下 2019-10-5 23:31
由E图
0->1
2->1
2->3
可推得D图
由D图
可推得E图
0->1
2->1
2->3
0->3
前后2幅E图数据显然矛盾.2019-10-6 16:22
//此文https://blog.csdn.net/shiyukun1998/article/details/44106483代码思路都写得不错,摘抄如下
/*
检查E图是否满足 存在k 使得 i->k j->k 的同时 存在t 使得 i 和 j 与t一个有边相连一个没有边相连
*/
//样例通过,提交AC.2019-10-6 16:43
#include <stdio.h>
#include <string.h>
#define maxn 305
int t,n,m,e[maxn][maxn];
int judge(){
int i,j,k,Have_inter,No_inter;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++){
Have_inter=No_inter=0;
for(k=0;k<n;k++){
if(e[i][k]&&e[j][k])Have_inter=1;
if(e[i][k]!=e[j][k])No_inter=1;//2个if中的k并不是同一个值
if(Have_inter&&No_inter)return 0;
}
}
return 1;
}
int main(){
int i,u,v;
scanf("%d",&t);
while(t--){
memset(e,0,sizeof(e));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)scanf("%d%d",&u,&v),e[u][v]=1;
if(judge())printf("Yes\n");
else printf("No\n");
}
return 0;
}