傳遞閉包:sorting it all out
阿新 • • 發佈:2022-01-08
給定n個不等式 判斷是否有邏輯錯誤
floyd傳遞閉包問題
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N=1010; int read() { int x=0,f=0,c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return f?-x:x; } struct Edge { int to,next; }e[N*N]; int head[N],cnt,deg[N]; void add(int a,int b){e[++cnt]=(Edge){b,head[a]};head[a]=cnt;deg[b]++;} int n,m; bool d[N][N]; queue<int> q; int ret; void clean() { for(int i=1;i<=n;i++) { head[i]=deg[i]=0; for(int j=1;j<=n;j++) d[i][j]=0; } ret=cnt=0; while(q.size()) q.pop(); } int floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j] |= d[i][k]&d[k][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if( d[i][j] &&d[j][i]) return -1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) continue; else if(!d[i][j]&&!d[j][i]) return 0; } return 1; } void topo() { for(int i=1;i<=n;i++) if(!deg[i]) q.push(i); while(q.size()) { int x=q.front(); q.pop(); putchar(x+'A'-1); for(int i=head[x];i;i=e[i].next) { int y=e[i].to; deg[y]--; if(!deg[y]) q.push(y); } } puts("."); } int main() { loop: while( ( n=read() )&& ( m=read() ) ) { clean(); for(int i=1;i<=m;i++) { int x=getchar()-'A'+1; bool opt=getchar()=='>'; int y=getchar()-'A'+1; getchar(); if(opt) d[x][y]=1,add(y,x); else d[y][x]=1,add(x,y); ret=floyd(); if(ret==1) { printf("Sorted sequence determined after %d relations: ", i); topo(); goto loop; } if(ret==-1) { printf("Inconsistency found after %d relations.\n",i); goto loop; } } if(ret==0) puts("Sorted sequence cannot be determined."); } return 0; }
這個題目的易錯點在於:
1 矛盾的優先順序高於推不出來結果 因此要優先判斷
2. 關於需不需要判斷i和j相等的問題 矛盾和推不出結果是兩種情況
3. 傳遞閉包的關係輸出: 拓撲排序