• 拓扑排序基础题——排序


    题目

    由于公司在2013年的销售业务成绩优秀,公司总经理心情大好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。于是总经理下令召开 m 方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工 a 的奖金应该比 b 高!”。总经理决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。
    输入格式
    第一行两个整数 n 和 m,表示员工总数和代表数;
    接下来有 m 行,每行 2 个整数 a 和 b,表示某个代表认为第 a 号员工奖金应该比第 b 号员工高。
    输出格式
    若无法找到合理方案,则输出“Poor Xed”;否则输出一个数表示最少总奖金。
    样例数据 1
    输入
    2 1
    1 2
    输出
    201
    备注
    【数据规模】
    80%的数据满足:n<=1000,m<=2000;
    100%的数据满足:n<=10000,m<=20000。

    很简单的一道拓扑排序

    如果A的工资要比B高,那就从B向A连一条边

    然后从入度为0的点开始统计

    然后用ff来记录每个点的工资,当从点i指向点j的时候f[j]=max(f[j],f[i]+1)f[j]=max(f[j],f[i]+1)

    最后的答案就是f[i],1&lt;=i&lt;=n∑f[i],1&lt;=i&lt;=n

    因为直接双层循环要超时,所以只能循环队列来做,但如果m,n到了151^5的时候,就只能用特殊的数据结构来维护入度了

    若一次循环中没有入度为0的点了,而还有点未处理,则有环,无解

    代码

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    int adj[20005],nxt[20005],to[20005],dep[10005],in[10005],f[10005],n,m,cnt;
    inline int sum(){
        int ans=0;
        for(int i=1;i<=n;i++)
        ans+=f[i];
        return ans;
    }
    inline void addedge(int u,int v)
    {
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,in[v]++;
    }
    inline void _(int k)
    {
        for(int e=adj[k];e;e=nxt[e])
        {
            in[to[e]]--;
            f[to[e]]=max(f[to[e]],f[k]+1);
        }
    }
    inline bool solve(){
        int tot=0;
        while(tot<n)
        {
            int t=0;
            for(int i=1;i<=n;i++)
            {
                if(in[i]==0)
                {
                    t++,tot++;
                    in[i]=1<<30;
                    _(i);
                }
            }
            if(!t)
            {
                return false;
            }
        }
        return true;
    }
    int main(){
        n=read(),m=read();
        int a,b;
        for(int i=1;i<=n;i++)
        f[i]=100;
        for(int i=1;i<=m;i++)
        {
            a=read(),b=read();
            addedge(b,a);
        }
        if(solve()) cout<<sum()<<endl;
        else cout<<"Poor Xed"<<'
    ';
        return 0;
    }
    
  • 相关阅读:
    Python高级网络编程系列之第二篇
    Python高级网络编程系列之第一篇
    Python高级网络编程系列之基础篇
    利用Python实现12306爬虫--查票
    Linux Shell脚本欣赏
    Linux Shell脚本 之 条件判断
    VMware Workstation虚拟网络VMnet0、VMnet1、VMnet8的图解
    Linux的虚拟机采用NAT方式时如何能在虚拟机中访问互联网
    Linux的虚拟机拷贝到另外的操作系统时,NAT方式的静态IP无效,一直是获取的DHCP动态地址
    Hadoop
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366500.html
Copyright © 2020-2023  润新知