hdu 2647 拓扑排序

题意:老板要给员工发工资,但是员工会有些小要求,就是老板你给我发的奖金要比比某某人多,如果老板不能满足所有人的要求,输出-1,否则求一下老板总共最少要发多少工资,基本工资是888元。

分析,这题以前做过,使用邻接表做的,又遇上了.明显的拓扑排序题。同一级的人发的奖金是一样的,相邻级别之间奖金差1,以前是用了一个结构体数组,保存了这个人的级别(也就是第几层),最后统计一下就好了。这次用vector数组存储有临边的两点,用栈s保存入读为0的点(当然也可以用队列保存),用另一个栈来保存与入度为零的点相连的点新变成的入读为0的点,因为新变成入度为零的点与以前入读为0的点发的工资相差1.当栈s空了以后,表示这一层的点都删完了,然后将保存在s1中的新的入度为0的点再放入栈s中。同时工资加1.

#include <cstdio>
#include <algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<iostream>
using namespace std;
const int maxn=20005;
int degree[maxn];
queue<int>q;
vector<int>v[maxn];
stack<int>s,st;
int main()
{
    //freopen("f.txt","r",stdin);
    int n,m;
    int x,y,k;
    while(cin>>n>>m ){
        memset(degree,0,sizeof(degree));
        for(int i=0;i<=n;i++)
            v[i].clear();
        for(int i=0;i<m;i++){
            scanf("%d%d",&x,&y);
            v[y].push_back(x);
            degree[x]++;
        }
        while(!q.empty())q.pop();
         int cnt=0;
        for(int i=1;i<=n;i++){
            if(degree[i]==0){
                q.push(i);
                cnt++;
                s.push(i);
            }
        }
        int sum=0,val=1;
       for(int i=1;i<n;i++){
            while(!s.empty()){
                int t=s.top();
                s.pop();
                for(int k=0;k<v[t].size();k++){
                    degree[v[t][k]]--;
                    if(degree[v[t][k]]==0){
                        cnt++;
                        sum+=val;
                        st.push(v[t][k]);
                    }
                }
            }
            bool flag=false;
            while(!st.empty()){
                if(!flag)flag=true,val++;
                s.push(st.top());
                st.pop();
            }
       }
        if(cnt==n)
        cout<<sum+888*n<<endl;
        else printf("-1\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值