zoukankan      html  css  js  c++  java
  • 图论 拓扑排序

    拓扑排序

    就系按图中节点度的个数来排序,入度少优先

    存图时用数组统计每个节点的入度,用队列/数组模拟,入度为0的先入队,遍历相邻节点,入度--,入度为0的再入队,同时存点,直至队列为空

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<string>
    using namespace std;
    const int INF=0x3f3f3f3f;
    typedef pair<int, int> p;
    typedef long long ll;
    #define fi first
    #define se second
    #define MAXN 100000+5
    #define NIL -1
    #define me(x) memset(x, -1, sizeof(x))
    #define mem(x) memset(x, 0, sizeof(x))
    struct node
    {
        int next, to; //edge[i].to 存 第i条边 的终点 .next存与边i同起点的前一条边
    }edge[MAXN];
    int head[MAXN]; //head[i] i为有边节点 head存该节点 边 的最大编号 存的是边
    int cnt;
    int indegree[MAXN];
    void add(int u, int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    int main()
    {
        int i, j, k, l;
        int n, m;
        int u, v;
        while(cin>>n>>m && (n||m)) //n节点个数 m边数 一个节点可能有多条边
        {
            cnt=0;
            me(head);
            mem(indegree);
            for(i=0; i<m; i++)
                cin>>u>>v, indegree[v]++, add(u, v);
            int que[MAXN];//存节点
            int iq=0;
            for(i=1; i<=n; i++)
                if(!indegree[i])
                que[iq++]=i;
            //int x[MAXN]; j=0;
            for(i=0; i<iq; i++)
                for(k=head[que[i]]; ~k; k=edge[k].next)   //注意 这里逆序
                 //x[j++]=k;
                 //for(k=j-1; k>=0; k--)
                {
                    indegree[edge[k].to]--;//顺序输出的话 这三行k改为x[k]
                    if(!indegree[edge[k].to])
                        que[iq++]=edge[k].to;
                }
            if(iq<n) {cout<<"There is a loop"<<endl;continue;}
            for(i=0; i<iq; i++)
                cout<<que[i]<<' ';
            cout<<endl;
        }
        return 0;
    }

     HDU 4857 逃生

    一般拓扑排序都按字典序最小输出,这里要求数字最小先输出

    先反向建图,改用优先队列,最后逆序输出就好了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    #define mem(x) memset(x, 0, sizeof(x))
    #define me(x) memset(x, -1, sizeof(x))
    #define lowbit(x) x&-x
    const ll MOD = 1e18;
    const int N = 2e5 + 5;
    struct node
    {
        int to, next;
    }e[N];
    int id, head[N], dep[N];
    void add(int u, int v)
    {
        e[id].to=v;
        e[id].next=head[u];
        head[u]=id++;
    }
    struct cmp
    {
        bool operator() (const int &a, const int &b) const
        {
            return a<b;
        }
    };
    int main()
    {
        int  i, j, k;
        int n, m, t;
        int u, v;
        int a, b;
        scanf("%d", &t);
        while(t--)
        {
            mem(dep); id=0; me(head);
            scanf("%d%d", &n, &m);
            for(i=0; i<m; i++)
                scanf("%d%d", &u, &v), add(v,u), dep[u]++;
            priority_queue< int, vector<int>, cmp> q;
            for(i=1; i<=n; i++)
                if(!dep[i]) q.push(i);
            int b[N], l=0;
            while(q.size())
            {
                k=q.top();
                b[l++]=k;
                q.pop();
                for(i=head[k]; ~i; i=e[i].next)
                {
                    if(dep[e[i].to]) dep[e[i].to]--;
                    if(!dep[e[i].to]) q.push(e[i].to);
                }
            }
            for(i=l-1; i>=1; i--)
                printf("%d ", b[i]);
            printf("%d
    ", b[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    常用软件自动化测试工具汇总
    推荐一款国产优秀的基于 AI 的 Web 自动化测试工具——kylinTOP 测试与监控平台
    常用性能测试工具
    一款类似loadRunner的优秀国产压力测试工具——kylinTOP测试与监控平台
    性能测试工具基本工作原理及仿真能力比较
    10大主流性能测试工具推荐
    AVL平衡二叉查找树
    图的深度优先和广度优先遍历
    向图中增加结点
    图数据类型的定义
  • 原文地址:https://www.cnblogs.com/op-z/p/11283090.html
Copyright © 2011-2022 走看看