拓扑排序

来源:互联网 发布:saa7130 tv card软件 编辑:程序博客网 时间:2024/06/03 20:31

它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:

从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
从图中删除该顶点和所有以它为起点的有向边。
重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。
这里写图片描述

于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

通常,一个有向无环图可以有一个或多个拓扑排序序列。

#include <iostream>#include <stdio.h>#include <string.h>#include <queue>#include <list>using namespace std;class graph{int v;list <int> *adj;queue <int> q;int *indegree;public:    graph(int v);    ~graph();    void addedge(int v, int w);    bool topological_sort();};graph::graph(int v){    this->v = v;    adj = new list<int>[v];    indegree = new int[v];    for(int i = 0; i< v; i++)    {        indegree[i] = 0;    }}graph::~graph(){    delete [] adj;    delete [] indegree;}void graph::addedge(int v, int w){    adj[v].push_back(w);    ++indegree[w];}bool graph::topological_sort(){    for(int i = 0; i < v; i++)    {        if(indegree[i] == 0)        {            q.push(i);        }    }    int cnt = 0;    while(!q.empty())    {        int v = q.front();        q.pop();        cout<<v<<" ";        ++cnt;        list<int>::iterator beg = adj[v].begin();        for(; beg != adj[v].end(); beg++)        {            if(!(--indegree[*beg]))            {                q.push(*beg);            }        }    }    if(cnt < v)    {        return false;    }    else{        return true;    }}int main(){    graph g(6);    g.addedge(5, 2);    g.addedge(5, 0);    g.addedge(4, 0);    g.addedge(4, 1);    g.addedge(2, 3);    g.addedge(3, 1);    g.topological_sort();    return 0;}

hdu reward

#include <iostream>#include <stdio.h>#include <string.h>#include <queue>using namespace std;int n, sum, ans;const int maxn = 10005;int into[maxn], head[maxn], money[maxn];struct node{    int to;    int next;}edge[2 * maxn];void top(){    queue <int> Q;    for(int i = 1; i <= n; i++)    {        if(into[i] == 0)        {            Q.push(i);        }    }    while(!Q.empty())    {       int v = Q.front();        sum += money[v];        Q.pop();        ans++;        for(int l = head[v]; l != -1; l = edge[l].next)        {            if(--into[edge[l].to] == 0)            {                Q.push(edge[l].to);                money[edge[l].to] = money[v] + 1;            }        }    }}int main(){    int m, a, b, tot;    while(scanf("%d%d", &n, &m) != EOF)    {        memset(head, -1, sizeof(head));        memset(into, 0, sizeof(into));        for(int i = 1; i <= n; i++)        {            money[i] = 888;        }        tot = 0;        sum = 0;        ans = 0;        while(m--)        {            scanf("%d%d", &a, &b);            edge[tot].to = a;            edge[tot].next = head[b];            head[b] = tot++;            into[a]++;        }        top();        if(ans != n)        {            sum = -1;        }        cout<<sum<<endl;    }}
0 0
原创粉丝点击