拓扑排序
拓扑排序经典运用于判断有向图种是否存在环。
拓扑排序的遍历也一定是无环的。
经典例题为:洛谷:https://www.luogu.com.cn/problem/P1347
同题:poj:http://poj.org/problem?id=1094 fjut:http://120.78.128.11/Problem.jsp?pid=1516
下面是ac代码和解释,带有几组数据。
这个题本人做了大概两三遍吧,
今天再做一次都还是wa了得90分,细节东西还是多
(wa点是:把add建边写在了bfs判断环的条件执行内,实际上建边根判断环并不存在条件关系,且如果有环而未建边,会导致答案应该是成环矛盾,而变成了有拓扑排序解,针对于A->A这种数据会wa掉。)
#include<bits/stdc++.h> #include<algorithm> using namespace std; #define N 202 #define mt(x) memset(x,0,sizeof x) typedef long long ll; void cn(ll x){cout<<x<<endl;} void cs(string x){cout<<x<<endl;} int n,m; int mp[N][N],in[N],inn[N],num; bool pd,vis[N],v[N]; char ans[N]; void add(int x,int y) { in[y]++; mp[x][y]=1; if(!v[x]){num++;v[x]=1;} if(!v[y]){num++;v[y]=1;} } bool bfs(int x,int y) { mt(vis); queue<int>q; q.push(x); while(q.size()) { x=q.front();q.pop(); vis[x]=1; for(int i=0;i<n;++i) { if(mp[x][i]) { if(i==y)return false; if(!vis[i]) { vis[i]=1; q.push(i); } } } } return true; } void topo(int i) { int cnt=0;mt(vis);mt(ans); queue<int>q; for(int i=0;i<n;++i) { inn[i]=in[i]; if(!in[i])q.push(i); } while(q.size()) { int x=q.front();q.pop(); vis[x]=1; ans[cnt++]='A'+x; //cs(ans); //每次队列里必须只有一个元素,所以pop后队列为空 ,否则退出 if(q.size())return ; for(int i=0;i<n;++i) { if(mp[x][i]==1) { inn[i]--; //cout<<" to->"<<char(i+'A')<<endl; if(!vis[i]&&!inn[i]) { vis[i]=1; q.push(i); //cout<<" 入:"<<char(i+'A')<<endl; } } } } if(cnt==n) { pd=false; cout<<"Sorted sequence determined after "<<i<<" relations: "<<ans<<'.'<<endl; //cs("ans1"); } } void solve() { cin>>n>>m; pd=true;num=0; for(int i=1;i<=m;++i) { string s;cin>>s; add(s[0]-'A',s[2]-'A'); if(!bfs(s[2]-'A',s[0]-'A')&&pd) { pd=false; cout<<"Inconsistency found after "<<i<<" relations."<<endl; //cs("ans2"); } if(num==n&&pd)topo(i);//给定的边已涉及到n个点,即可以开始进行拓扑排序 } if(pd)cs("Sorted sequence cannot be determined.");//cs("ans3"); } /* 分析3种情况 正常排序:在已入边元素数=n 开始判断是否排序成功 ,完美的拓扑排序为每次队列循环只有一个新元素入队 矛盾:bfs判断环 无法排序:点数不够or一次循环入队有多种情况 建图 a<b b在a之后,即in[b]++; 示例数据 4 6 C<D C<B B<A C<D D<A A<A Inconsistency found after 6 relations. AA边为矛盾 6 6 A<F B<D C<E F<D D<E E<F Inconsistency found after 6 relations. 这个是针对多选的情况,本题是不认可的,会判断为矛盾 5 5 A<B B<C C<D D<E E<A Sorted sequence determined after 4 relations: ABCDE 顺序判读即可,第四个有完美拓扑排序,不必考虑第五个矛盾的情况 4 6 A<B A<C B<C C<D B<D A<B Sorted sequence determined after 4 relations: ABCD. 基本样例 */ int main() { ios::sync_with_stdio(false); cin.tie(0); solve(); return 0; }
如果是多组输入
需要初始化
void init() { pd=true;num=0; mt(mp);mt(in);mt(v);mt(ans); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!