1019 集合论与图论
集合论与图论对于小松来说是比数字逻辑轻松,比数据结构难的一门专业必修课。虽然小松在高中的时候已经自学过了离散数学中的图论,组合,群论等知识。但对于集合论,小松还是比较陌生的。集合论的好多东西也涉及到了图论的知识。
在第四讲的学习中,小松学到了“有序对”这么一个概念,即用<x, y>表示有序对x和y。要注意的是有序对<x, y>不等于有序对<y, x>。对于一个有序对集合R={<x,y>, <y, z>, <x, z>,……},我们说R是传递的,当且仅当他满足下面的性质:
红色字体用直观的语言描述是:如果存在<x, y>∈R,<y, z>∈R,那么一定存在<x, z>∈R。
这里集合R可以对应到一个有向图G,有序对<x ,y>对应到了G中的一条有向边。 你现在的任务是,对于任意给定的一个简单有向图G(同一有向边不出现两次),判断G是否具有传递性。
输入文件set.in第一行包含测试数据的个数T(1<=T<=10)。接下来T组测试数据,每组测试数据第一行包含两个个整数n和m(1<=n<=1000, n<=m<=100000),表示G中元素个数和有向边的个数,接下来的m行每行2个整数x, y(1<=x,y<=n)表示x与y之间有一条有向边连接。
对于每组数据,如果G是传递的,你需要向输出文件set.out输出一行”Yes”, 否则输出一行”No”。
2
3 3
1 2
1 3
2 3
4 5
1 2
1 3
1 4
2 3
3 4
Yes
No
有30%满足1<=n<=100, 1<=m<=10000;
有100%的数据满足1<=n<=1000, 1<=m<=100000;
分类标签 Tags 点此展开
条件的话题目已经已经说得很清楚了,就是x,y,z之间的关系,而xyz又恰好是三个字母,这样我们用Flyod就可以完美解决了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int MAXN=1001; 6 const int maxn=0x7fffffff; 7 int map[MAXN][MAXN]; 8 int vis[100001]; 9 int x,y,z; 10 int main() 11 { 12 int t; 13 scanf("%d",&t); 14 while(t--) 15 { 16 memset(map,0,sizeof(map)); 17 int n,m; 18 scanf("%d%d",&n,&m); 19 /*for(int i=1;i<=n;i++) 20 for(int j=1;j<=n;j++) 21 map[i][j]=maxn; 22 for(int i=1;i<=n;i++) 23 map[i][i]=0;*/ 24 for(int i=1;i<=m;i++) 25 { 26 scanf("%d%d",&x,&y); 27 map[x][y]=1; 28 } 29 int flag=0; 30 for(int x=1;x<=n;x++) 31 { 32 for(int y=1;y<=n;y++) 33 { 34 if(map[x][y]==1) 35 for(int z=1;z<=n;z++) 36 { 37 /*if(map[i][j]||(map[i][k]&&map[k][j])) 38 vis[i]=vis[j]=1;*/ 39 if(map[y][z]==1) 40 { 41 if(map[x][z]==0) 42 { 43 flag=1; 44 break; 45 } 46 } 47 } 48 } 49 } 50 /*for(int i=1;i<=n;i++) 51 { 52 if(vis[i]==0) 53 { 54 flag=1; 55 break; 56 } 57 }*/ 58 if(flag==1) 59 { 60 printf("No "); 61 } 62 else 63 { 64 printf("Yes "); 65 } 66 } 67 return 0; 68 }