HDU:1285 确定比赛名次 (拓扑排序)

 

题意:拓扑排序,已保证无环,要求输出最小字典序

思路:拓扑排序模版题+优先队列。

拓扑排序:首先寻找入度为0的顶点加入到优先队列中。将最优先顶点弹出,然后删除掉从该顶点出发的所有边(边的另一顶点入度减一),当出现入度为0的顶点时加入到优先队列中,如此循环直到队列为空。

 

图用邻接表实现。

这里用优先队列保证每次先输出的是最小的数字。

 

 

#include 
#include 
#include 
#include 
#include 
#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, greater >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;
}


 

你可能感兴趣的:(HDU)