220 字
1 分钟
图论-拓扑排序
- 要求每个节点的前置节点都在这个节点之前
- 排序前提:无环有向图
- 拓扑排序的顺序可能不止一种
- 拓扑排序可以判断有没有环
Kahn算法 删点法
- 用队列维护一个入度为0的节点的集合
- 初始化,队列q压入所有入度为0的点
- 每次从q中取出一个点x放入数组tp
- 然后将x的所有出边删除,若将边(x,y)删除后,y的入度变为0,则将y压入q中,重复步骤2 3
- 直到队列为空,若tp中的元素个数等于节点个数,则有拓扑序;否则有环
int n,m;vector<int> adj[N],tp;int din[N];
bool toposort(){ queue<int> q; for(int i=1;i<=n;i++){ if(din[i]==0) q.push(i); } while(!q.empty()){ int x=q.front(); q.pop(); tp.push_back(x); for(int y:adj[x]){ if(--din[y]==0) q.push(y); } } return int(tp.size())==n;}
void solve() { cin>>n>>m; for(int i=0;i<m;i++){ int u,v;cin>>u>>v; adj[u].push_back(v); din[v]++; } if(toposort()){ for(int v:tp){ cout<<v<<" "; } } else{ cout<<"-1"; }}DFS 算法
例题
B3644 【模板】拓扑排序 / 家谱树 - 洛谷
套上面模板就能过
P1113 [USACO02FEB] 杂务 - 洛谷
const int N = 1e5+5;
int n;ll costs[N];int din[N];vector<int> adj[N];
struct e{ int od; ll cost;
bool operator<(const e& other) const{ return cost>other.cost; }};
ll toposort(){ ll ans=0; priority_queue<e> q; for(int i=1;i<=n;i++){ if(din[i]==0){ q.push({i,costs[i]}); } } while(!q.empty()){ e x=q.top(); q.pop(); int node=x.od; ll c=x.cost; for(int y:adj[node]){ if(--din[y]==0){ q.push({y,c+costs[y]}); ans=max(ans,c+costs[y]); } } } return ans;}
void solve() { cin>>n; for(int i=1;i<=n;i++){ int u,v;cin>>u; cin>>costs[u]; cin>>v; while(v!=0){ adj[v].push_back(u); din[u]++; cin>>v; } } ll ans=toposort(); cout<<ans;} 分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐








