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

     for(int i=1;i<=scc;i++) if(!ru[i]) q.push(i);
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=hd[x];i;i=ed[i].next){
                hav[ed[i].to] += hav[x];
                --ru[ed[i].to];
                if(!ru[ed[i].to]) q.push(ed[i].to);
            }
        }
    View Code

    拓扑排序两种作用
    1.判断图中是否有环

    2.统计某些问题的答案

    判断是否有环的话

    for(int i=1;i<=n;i++) if(!ru[i]) q.push(i);
        while(!q.empty()){
            int x=q.front();q.pop();caozuo++;
            for(int i=hd[x];i;i=ed[i].next){
                hav[ed[i].to] += hav[x];
                --ru[ed[i].to];
                if(!ru[ed[i].to]) q.push(ed[i].to);
            }
        }
        if(caozuo<n)puts("0");
    View Code

    他的出队顺序就是它的拓扑序

    • 找出图中0入度的顶点;
    • 依次在图中删除这些顶点,删除后再找出0入度的顶点;
    • 然后再删除……再找出……
    • 直至删除所有顶点,即完成拓扑排序

     [HAOI2016]食物链

    题目描述

    如图所示为某生态系统的食物网示意图,据图回答第1小题现在给你n个物种和m条能量流动关系,求其中的食物链条数。物种的名称为从1到n编号M条能量流动关系形如a1 b1a2 b2a3 b3......am-1 bm-1am bm其中ai bi表示能量从物种ai流向物种bi,注意单独的一种孤立生物不算一条食物链

    输入输出格式

    输入格式:

    第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(数据保证输入数据符号生物学特点,且不会有重复的能量流动关系出现)1<=N<=100000 0<=m<=200000题目保证答案不会爆 int

    输出格式:

    一个整数即食物网中的食物链条数

    输入输出样例

    输入样例#1:
    10 16
    1 2
    1 4
    1 10
    2 3
    2 5
    4 3
    4 5
    4 8
    6 5
    7 6
    7 9
    8 5
    9 8
    10 6
    10 7
    10 9

    输出样例#1: 
    9


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define maxn 2000005
    using namespace std;
    struct data
    {
        int to,next;
    }e[maxn];
    vector<int>ed;
    queue<int>q;
    int n,m,res=0;
    int ne=0;
    int last[maxn];
    int ru[maxn],cu[maxn],ans[maxn];
    void ins(int a,int b)
    {
        e[++ne].to=b;e[ne].next=last[a];
        last[a]=ne;
    }
    int main()
    {
    //    freopen("a.in","r",stdin);
        cin>>n>>m;
        for(int i=1;i<=m;++i)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            ins(a,b);
            ++ru[b];++cu[a];
        }
        for(int i=1;i<=n;++i)if(ru[i]==0&&cu[i]==0)--res;
        for(int i=1;i<=n;++i)
        {
            if(ru[i]==0)
            {
                ans[i]=1;
                q.push(i);
            }
            if(cu[i]==0)ed.push_back(i);
    //把入度为0的丢进去 用ed存出度为0的点
        }
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=last[x];i;i=e[i].next)
            {
                ans[e[i].to]+=ans[x];
                ru[e[i].to]--;
                if(!ru[e[i].to])q.push(e[i].to);
            }
        }
    //遍历图 统计答案 出现新的入度为0的点再丢进去
        for(int i=0;i<ed.size();++i)res+=ans[ed[i]];
        cout<<res;
        puts("");
        fclose(stdin);
        return 0;
    }
    View Code



  • 相关阅读:
    c8051f交叉开关
    8052定时器2的用法
    poj1010
    poj2101
    poj1958
    poj3444
    poj2977
    DataTable 相关操作
    C#中string和StringBuilder的区别
    DataTable排序,检索,合并,筛选
  • 原文地址:https://www.cnblogs.com/gc812/p/7786571.html
Copyright © 2011-2022 走看看