拓扑排序
一:使用DFS实现
#include <bits/stdc++.h>
using namespace std;
#define maxn 10000 + 10
int c[maxn],topo[maxn], k;
int n, r;
vector<int>G[maxn];
int dfs(int u)
{
c[u] = -1;
for(int i=0; i<G[u].size(); i++)
{
int &t = G[u][i];
if(c[t] < 0) return false;
if(!c[t] && !dfs(t)) return false;
}
c[u] = 1;
topo[k--] = u;
return true;
}
bool Topo()
{
for(int i=n; i>=1; i--)
if(!c[i])
{
if(!dfs(i)) return false;
}
return true;
}
int main()
{
while(~scanf("%d%d", &n, &r))
{
int a, b;
k = n;
memset(c, 0, sizeof(c));
for(int i=0; i<r; i++)
{
cin>>a>>b;
G[a].push_back(b);
}
bool flag = Topo();
cout<<flag<<endl;
for(int i=1; i<=n; i++)
cout<<topo[i]<<" ";
}
return 0;
}
二:使用入度概念以及队列处理
1.使用一般队列
queue<int>q;
//priority_queue<int,vector<int>,greater<int>>q;
//优先队列的话,会按照数值大小有顺序的输出
//此处为了理解,暂时就用简单队列
int topo()
{
for(int i=1; i<=n; i++)
{
if(indegree[i]==0)
{
q.push(i);
}
}
int temp;
while(!q.empty())
{
temp=q.front();//如果是优先队列,这里可以是top()
printf("%d->",temp);
q.pop();
for(inti=1; i<=n; i++) //遍历从temp出发的每一条边,入度--
{
if(map[temp][i])
{
indegree[i]--;
if(indegree[i]==0)q.push(i);
}
}
}
}
2.使用优先队列(这里定义越大的整数拥有越大的优先级)
#include <bits/stdc++.h>
using namespace std;
#define maxn 100000+10
struct cmp
{
bool operator()(int a, int b)
{
return a < b;
}
};
priority_queue<int, vector<int>, cmp>Q;
int deg[maxn];
vector<int>G[maxn];
int main()
{
int n, r;
int u, v;
cin>>n>>r;
for(int i=0; i<r; i++)
{
cin>>u>>v;
G[u].push_back(v);
deg[v]++;
}
for(int i=1; i<=n; i++)
if(deg[i] == 0)
{
Q.push(i);
}
while(!Q.empty())
{
int t = Q.top();///因为使用优先队列 必须在与其相关节点入队之前将其pop这样不会因为优先性对于拓扑序有所影响
///换而言之,当入度为0时该节点已经是自由的,所有在这之前的节点已经得到安排,即拓扑序已经得到实现
cout<<t<<" ";
Q.pop();
for(int i=0; i<G[t].size(); i++)
{
int &tmp = G[t][i];
deg[tmp]--;
if(!deg[tmp]) Q.push(tmp);
}
}
return 0;
}
时间: 2024-12-07 08:40:22