今天离散老师布置了一个编程作业:用代码实现关系性质的判断。然后我就结合所学知识写了写,如果哪里有不足欢迎批评指正。
自反性:∀x∈A,有<x,x>∈R。
关系矩阵特点:主对角线元素全为1.
关系图的特点:图中每个顶点都有环。
代码:
int refl(){ bool flag=false; for(int i=1;i<=n;i++){ if(!e[i][i]){ flag=true; break; } } if(flag) return 0; else return 1; }
反自反性:∀x∈A,有<x,x>∉R。
关系矩阵特点:主对角线元素全为0.
关系图特点:图中每个顶点都没环。
代码:
int irrefl(){ bool flag=false; for(int i=1;i<=n;i++){ if(e[i][i]){ flag=true; break; } } if(flag) return 0; else return 1; }
对称性:若<x,y>∈R,则<y,x>∈R。
关系矩阵特点:矩阵为对称矩阵。
关系图特点:如果两个顶点之间有边,一定是一对方向相反的边。
代码:
int sym(){ bool flag=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(e[i][j]&&!e[j][i]){ flag=true; } } if(flag) break; } if(flag) return 0; else return 1; }
反对称性:
若<x,y>∈R,且x不等于y,则<y,x>∉R。
关系矩阵特点:如果r[i][j]=1,且i不等于j,则r[j][i]=0.
关系图特点:如果两个顶点之间有边,一定是一条有向边。
代码:
int irsym(){ bool flag=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j){ if(e[i][j]&&e[j][i]){ flag=true; break; } } else continue; } if(flag) break; } if(flag) return 0; else return 1; }
传递性:
若<x,y>∈R,且<y,z>∈R,则<x,z>∈R。
关系图特点:如果顶点xi到顶点xj有边,xj到xk有边,则从xi到xk有边。
代码:
int tra(){ memset(book,0,sizeof(book)); for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(e[i][k]&&e[k][j]){ book[i][j]=1;//表示两点之间可以到达 } } } } bool flag=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(book[i][j]){ flag=true; break; } } if(flag) break; } if(flag) return 1; else return 0; }
总代码:
#include<bits/stdc++.h> using namespace std; int n,m;//n代表集合中元素的个数,m表示集合r中序偶的个数 int e[101][101];//关系矩阵 int a[101];//集合a int vis[101][101],book[101][101]; struct node { int x, y;//x为第一元素,y为第二元素 }r[100010];//集合r的序偶 int refl(){ bool flag=false; for(int i=1;i<=n;i++){ if(!e[i][i]){ flag=true; break; } } if(flag) return 0; else return 1; } int irrefl(){ bool flag=false; for(int i=1;i<=n;i++){ if(e[i][i]){ flag=true; break; } } if(flag) return 0; else return 1; } int sym(){ bool flag=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(e[i][j]&&!e[j][i]){ flag=true; } } if(flag) break; } if(flag) return 0; else return 1; } int irsym(){ bool flag=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j){ if(e[i][j]&&e[j][i]){ flag=true; break; } } else continue; } if(flag) break; } if(flag) return 0; else return 1; } int tra(){ memset(book,0,sizeof(book)); for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(e[i][k]&&e[k][j]){ book[i][j]=1;//表示两点之间可以到达 } } } } bool flag=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(book[i][j]){ flag=true; break; } } if(flag) break; } if(flag) return 1; else return 0; } int main() { while (~scanf("%d%d",&n,&m)) { getchar(); memset(vis,0,sizeof(vis)); memset(e,0,sizeof(e)); for (int i = 1; i <= n; i++) { scanf("%d",&a[i]);//输入集合a } getchar(); for(int i=1;i<=m;i++){ scanf("%d %d",&r[i].x,&r[i].y);//输入集合r的第一第二元素 vis[r[i].x][r[i].y]=1; } //生成关系矩阵 for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(vis[a[i]][a[j]]) e[a[i]][a[j]]=1; } } if(refl()){ printf("具有自反性\n"); printf("关系矩阵为\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d ",e[i][j]); } printf("\n"); } } if(irrefl()){ printf("具有反自反性\n"); printf("关系矩阵为\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d",e[i][j]); } printf("\n"); } } if(sym()){ printf("具有对称性\n"); printf("关系矩阵为\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d",e[i][j]); } printf("\n"); } } if(irsym()){ printf("具有反对称性\n"); printf("关系矩阵为\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d",e[i][j]); } printf("\n"); } } if(tra()){ printf("具有传递性\n"); printf("关系矩阵为\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d",e[i][j]); } printf("\n"); } } } return 0; }