拓扑排序
百度百科:点这里
大致过程:选择一个入度为0的结点,依次删除与它相连的所有边,继续找下一个入度为0的点,反复操作,直到图空,或者不存在入度为0的点为止。
两种实现:意思都一样,但根据自己需求,任意选取;
代码一:
#include<iostream>
#include<cstring>
using namespace std;
int G[1000][1000]; //邻接图
int vis[1000]; //标记
int n;
void toposort(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(!vis[j]){
vis[j]--; //注意,要标记一下
cout<<j;
if(i!=n)cout<<" ";
else cout<<endl;
for(int k=1;k<=n;k++){ //删除以j为前驱的边
if(G[j][k]){
vis[k]--;
}
}
break;
}
}
}
}
int main(){
int m;
while(cin>>n>>m&&m&&n)
{ memset(vis,0,sizeof(vis));
memset(G,0,sizeof(G));
int p1,p2;
while(m--){
cin>>p1>>p2;
if(!G[p1][p2]){
G[p1][p2]=1;
vis[p2]++;
}
}
toposort();
}
return 0;
}
代码二:
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
vector<int> ans;
int G[800][800];
int vis[800];
int n,m;
priority_queue<int,vector<int>,greater<int> >q;
//优先队列,会按照数值大小有顺序的输出
void toposort()
{
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
{
q.push(i);
}
}
int temp;
while(!q.empty())
{
temp=q.top();
// printf("%d->",temp);
ans.push_back(temp);
q.pop();
for(int i=1;i<=n;i++)//遍历从temp出发的每一条边,入度--
{
if(G[temp][i])
{
vis[i]--;
if(vis[i]==0)
q.push(i);
}
}
}
}
int main()
{
int x,y;
while(~scanf("%d%d",&n,&m))
{ ans.clear();
memset(vis,0,sizeof(vis));
memset(G,0,sizeof(G));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(!G[x][y])
{
G[x][y]=1;
vis[y]++;
}
}
toposort();
for(int i=0;i<ans.size();i++){
cout<<ans[i];
if(i!=ans.size()-1){
cout<<" ";
}
else cout<<endl;
}
}
return 0;
}