题意:拓扑排序,已保证无环,要求输出最小字典序
思路:拓扑排序模版题+优先队列。
拓扑排序:首先寻找入度为0的顶点加入到优先队列中。将最优先顶点弹出,然后删除掉从该顶点出发的所有边(边的另一顶点入度减一),当出现入度为0的顶点时加入到优先队列中,如此循环直到队列为空。
图用邻接表实现。
这里用优先队列保证每次先输出的是最小的数字。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define MAXN 505
using namespace std;
struct EdgeNode
{
int adjvert;
EdgeNode *next;
};
struct VertNode
{
int in;
int data;
EdgeNode* firstedge;
};
typedef struct
{
VertNode adjlist[MAXN];
int numVert,numEdge;
} graphAdjList,*GraphAdjList;
int n,m;
void CreateALGraph(GraphAdjList GL)
{
GL->numVert=n;
GL->numEdge=m;
for(int i=1; i<=GL->numVert; ++i)
{
GL->adjlist[i].data=i;
GL->adjlist[i].in=0;
GL->adjlist[i].firstedge=NULL;
}
EdgeNode* e;
for(int i=1; i<=GL->numEdge; ++i)
{
int u,v;
scanf("%d%d",&u,&v);
e=new EdgeNode;
e->adjvert=v;
e->next=GL->adjlist[u].firstedge;
GL->adjlist[u].firstedge=e;
GL->adjlist[v].in++;
}
}
void Toposort(GraphAdjList GL)
{
priority_queue<int, vector<int>, greater<int> >q;
for(int i=1; i<=GL->numVert; ++i)
if(GL->adjlist[i].in==0) q.push(i);
bool fir=false;
while(!q.empty())
{
int gettop=q.top();
q.pop();
if(!fir)
{
printf("%d",gettop);
fir=true;
}
else printf(" %d",gettop);
for(EdgeNode *e=GL->adjlist[gettop].firstedge; e; e=e->next)
{
GL->adjlist[e->adjvert].in--;
if(GL->adjlist[e->adjvert].in==0)
q.push(e->adjvert);
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
graphAdjList g;
CreateALGraph(&g);
Toposort(&g);
printf("\n");
}
return 0;
}