• UVA-10305 Ordering Tasks (拓扑排序)


    题目大意:给出n个点,m条关系,按关系的从小到大排序。

    题目分析:拓扑排序的模板题,套模板。

    kahn算法:

    伪代码:

    Kahn算法:

    摘一段维基百科上关于Kahn算法的伪码描述:

    L← Empty list that will contain the sorted elements
    S ← Set of all nodes with no incoming edges
    while S is non-empty do
        remove a node n from S
        insert n into L
        foreach node m with an edge e from nto m do
            remove edge e from thegraph
            ifm has no other incoming edges then
                insert m into S
    if graph has edges then
        return error (graph has at least onecycle)
    else
        return L (a topologically sortedorder)

    维护一个入度为0的点的集合S,一个初始为空的集合L,L存放排好序的序列。将集合S中的一个点加入集合L后,在S中删除该点并破坏所有从该点出发的边,若被破坏的边的另一端点的入度为0,则加入S,一直处理到S为空。若仍有边存在,则存在环路,反之,集合L中的元素便是按拓扑序排放的。时间复杂度为O(E+V)。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    int mp[105][105],n,m,d[105];
    vector<int>l;
    queue<int>q;
    
    int judge(int u)
    {
        int cnt=0;
        for(int i=1;i<=n;++i)
            if(mp[i][u])
                ++cnt;
        return cnt;
    }
    
    void solve()
    {
        l.clear();
        while(!q.empty()){
            int u=q.front();
            q.pop();
            l.push_back(u);
    
            for(int i=1;i<=n;++i){
                if(mp[u][i]){
                    mp[u][i]=0;
                    --d[i];
                    if(d[i]==0)
                        q.push(i);
                }
            }
        }
        for(int i=0;i<n;++i)
            printf("%d%c",l[i],(i==n-1)?'
    ':' ');
    }
    
    int main()
    {
        int a,b;
        while(scanf("%d%d",&n,&m)&&(n+m))
        {
            memset(mp,0,sizeof(mp));
            while(m--){
                scanf("%d%d",&a,&b);
                mp[a][b]=1;
            }
    
            while(!q.empty())
                q.pop();
            for(int i=1;i<=n;++i){
                d[i]=judge(i);
                if(d[i]==0)
                    q.push(i);
            }
            solve();
        }
        return 0;
    }
    

      

    基于dfs的拓扑排序:

    同样摘录一段维基百科上的伪码:

    L ← Empty list that will contain the sorted nodes
    S ← Set of all nodes with no outgoing edges
    for each node n in S do
        visit(n)
    function visit(node n)
        if n has not been visited yet then
            mark n as visited
            for each node m with an edgefrom m to ndo
                visit(m)
            add n to L

    维护一个出度为0的点的集合S,一个初始为空的集合L,L存放排好序的序列。对于集合S中的一个点e,先将所有应该排在e前面的点放到集合L之后,再将点e放入集合L。时间复杂度为O(E+V)。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    vector<int>l;
    queue<int>q;
    int n,m,mp[105][105],mark[105];
    
    bool judge(int u)
    {
        for(int i=1;i<=n;++i)
            if(mp[u][i])
                return false;
        return true;
    }
    
    void visit(int u)
    {
        if(!mark[u]){
            mark[u]=1;
            for(int i=1;i<=n;++i)
                if(mp[i][u])
                    visit(i);
            l.push_back(u);
        }
    }
    
    void solve()
    {
        l.clear();
        memset(mark,0,sizeof(mark));
        while(!q.empty()){
            int u=q.front();
            q.pop();
            visit(u);
        }
        for(int i=0;i<n;++i)
            printf("%d%c",l[i],(i==n-1)?'
    ':' ');
    }
    
    int main()
    {
        int a,b;
        while(scanf("%d%d",&n,&m)&&(n+m))
        {
            memset(mp,0,sizeof(mp));
            while(m--)
            {
                scanf("%d%d",&a,&b);
                mp[a][b]=1;
            }
    
            while(!q.empty())
                q.pop();
            for(int i=1;i<=n;++i){
                if(judge(i))
                    q.push(i);
            }
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    Jmeter_Beanshell_使用Java处理JSON块
    BeanShell Processor_使用Java处理脚本
    MySQL_explain关键字分析查询语句
    LoadRunner11_录制脚本时的浏览器版本
    Jmeter_实现Excel文件导出到本地
    Jmeter_录制HTTPS
    性能测试常用sql语句
    LoadRunner11_MySQL数据库脚本
    LoadRunner11_录制Oracle数据库脚本
    实现liunx之间无密码访问——ssh密匙
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4857254.html
Copyright © 2020-2023  润新知