D112 最短路→传递闭包 Floyd 算法 P1347 排序
D112 最短路→传递闭包 Floyd 算法 P1347 排序_哔哩哔哩_bilibili
给 m 个小于关系,判断字母之间的关系:若矛盾,输出发生位置;若不确定,输出不确定;若确定,输出顺序
思路
枚举 m 个小于关系,每次做 Floyd 求传递关系,$d[i][j]=1$ 表示 $i<j$,然后进行检查:
1. 如果 $d[i][i]=1$,那么就是出现了环,发现矛盾,返回 opt = 1
2. 如果 $d[i][j]=d[j][i]=0$,那么说明 $i、j$ 两个点之间的关系不确定,返回 opt = 0
3. 异常情况都排除了,说明 n 个点的大小关系确定,返回 opt = 2

相关板子:
D111【模板】最短路→传递闭包 Floyd 算法 B3611 传递闭包 - 董晓 - 博客园
// 传递闭包 Floyd 算法 O(m*n^3) #include<bits/stdc++.h> using namespace std; const int N=30; int n,m; int d[N][N],vis[N]; void floyd(){ for(int k=0; k<n; k++) for(int i=0; i<n; i++) for(int j=0; j<n; j++) d[i][j]|=d[i][k]&d[k][j]; //d[i,j]=1 表示 i<j } int check(){ for(int i=0; i<n; i++)if(d[i][i]) return 1; //发现矛盾 for(int i=0; i<n; i++) for(int j=0; j<i; j++) if(!d[i][j] && !d[j][i]) return 0; //关系不确定 return 2; //关系确定 } char get(){ for(int i=0; i<n; i++)if(!vis[i]){ //若i未输出 bool flag=true; for(int j=0; j<n; j++)if(!vis[j] && d[j][i]){ //j未输出且j<i,则不合法 flag=false; break; } if(flag){vis[i]=true; return 'A'+i;} } } int main(){ cin>>n>>m; int opt=0,pos; for(int i=1; i<=m; i++){ char a,b,c; cin>>a>>b>>c; if(opt==0){ //若关系不确定 d[a-'A'][c-'A']=1; floyd(); //Floyd求传递关系 opt=check(); pos=i; //记录当前关系位次 } } if(opt==0)puts("Sorted sequence cannot be determined."); if(opt==1)printf("Inconsistency found after %d relations.\n",pos); if(opt==2){ printf("Sorted sequence determined after %d relations: ",pos); for(int i=0; i<n; i++) printf("%c",get()); printf(".\n"); } }
// 传递闭包 拓扑排序 #include<bits/stdc++.h> using namespace std; const int N=30; int n,m,pre[N]; vector<int> e[N]; bool g[N][N]; int bfs(int k){ int d[N]={0};d[0]=1; queue<int> q; q.push(0); while(q.size()){ int u=q.front(); q.pop(); for(int v:e[u]){ if(d[v]<d[u]+1){ d[v]=d[u]+1; pre[n+1]=v; pre[v]=u; //记录前驱 q.push(v); } if(d[v]>n+2) return 1; //发现矛盾 } } if(d[n+1]==n+2) return 2; //关系确定 return 0; //关系不确定 } void dfs(int v){ if(pre[v]) dfs(pre[v]); cout<<char('A'+v-1); //输出 } int main(){ cin>>n>>m; for(int i=1; i<=n; i++) e[0].push_back(i), e[i].push_back(n+1); //虚拟源点、汇点 int opt=0,p; for(int i=1; i<=m; i++){ char a,b,c; cin>>a>>b>>c; if(opt==0){ //若关系不确定 int u=a-'A'+1, v=c-'A'+1; if(!g[u][v]) e[u].push_back(v), g[u][v]=1; //去重边 opt=bfs(i); p=i; //记录当前关系位次 } } if(opt==0) puts("Sorted sequence cannot be determined."); if(opt==1) printf("Inconsistency found after %d relations.",p); if(opt==2){ printf("Sorted sequence determined after %d relations: ",p); dfs(pre[n+1]); printf("."); } }
浙公网安备 33010602011771号