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