hdu 2647 拓扑排序

来源:互联网 发布:ubuntu查找源命令 编辑:程序博客网 时间:2024/06/07 12:55

题意:老板要给员工发工资,但是员工会有些小要求,就是老板你给我发的奖金要比比某某人多,如果老板不能满足所有人的要求,输出-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
原创粉丝点击