问题 B: PIPI发工资(拓扑排序遍历)

题目描述

PIPI开了一个工厂,工厂里面有许许多多的员工。每次要发工资的时候PIPI就开始思考了,如何才能给员工发最少的工资呢?
发工资的原则是这样的: 每个员工的工资都是一个整数,其中基本工资是888元,但是如果 A 是 B的上司,那么A的工资就要比B高。
现在给出员工的数量和员工之间的关系,PIPI想问下胖虎他最少要发多少钱??

输入

输入包含多组测试用例。
对于每一组测试用例,第一行包含两个整数 n (n<=10000)和 m (m<=20000)。表示PIPI工厂里面员工数量以及员工之间的关系数目。
接下来m行每一行包含两个整数 a和 b 。代表 a 是 b的的上司(1<=a,b<=n)。

输出

对于每组测试用例,输出PIPI最少需要发多少工资。如果PIPI没办法发工资,输出-1。

样例输入

2 1
1 2
2 2
1 2
2 1

样例输出

1777
-1

ps:一开始想用动态规划计算工资后来发现无法判断是否有有向环
并查集只能找无向环
想要找有向环有种2途径,拓扑排序和深搜

拓扑排序遍历
可以判断是否有环

#include 
#include 
#include 
using namespace std;
int n,m;
int indegree[10005];
int salary[10005];
int head[10005];
struct Edge{
int to;
int next;
}Edge[20000];
int t;
void add(int u,int v){
Edge[t].to=v;
Edge[t].next=head[u];
head[u]=t++;
}
int main(){
    int i,a,b,Count,ans;
    stack<int> s;
    while(scanf("%d %d",&n,&m)!=EOF){
        t=1;Count=0;ans=0;
            while(!s.empty()) s.pop();
        for(i=1;i<=n;i++){
            indegree[i]=0;salary[i]=0;head[i]=-1;}
        for(i=0;i<m;i++){
            scanf("%d %d",&a,&b);
            add(b,a);
            indegree[a]++;
        }
        for(i=1;i<=n;i++)
        if(!indegree[i]) s.push(i);
        while(!s.empty()){
            int u=s.top();s.pop();Count++;
            for(i=head[u];i!=-1;i=Edge[i].next)
            {int v=Edge[i].to;
            salary[v]=salary[v]>salary[u]+1?salary[v]:salary[u]+1;
            if(!--indegree[v]) s.push(v);
            }
        }
        if(Count<n) {printf("-1\n");continue;}
        for(i=1;i<=n;i++)
            {ans+=salary[i];}
        ans+=888*n;
        printf("%d\n",ans);
    }
return 0;
}

你可能感兴趣的:(问题 B: PIPI发工资(拓扑排序遍历))