Reward
题意:每个人的起始金额是888,有些人觉得自己做的比另一个人好所以应该多得一些钱,问最少需要花多少钱,如果不能满足所有员工的要求,输出 -1
样例1:
2 1
1 2 输出1777
1认为自己的报酬应该比2多,所以2为888,1为889是最小的情况
样例2:
5 4
1 2 2 5 2 4 4 3 输出4446
相当于给定一张图,n个节点,m条边,问你是否存在环,若存在,则输出-1,否则如下面思路所示
思路:可以把整张图反过来,若存在u->v,则实际上连接v->u,v的入度为0,那么我们就可以保证初始入度为0的点金额一定是888,在队列过程中,后面的点都继承前面的金额并+1,
1 #include<iostream> 2 #include<cstring> 3 #include<math.h> 4 #include<stdlib.h> 5 #include<cstring> 6 #include<cstdio> 7 #include<utility> 8 #include<algorithm> 9 #include<map> 10 #include<queue> 11 using namespace std; 12 typedef long long ll; 13 inline int read(){ 14 int X=0,w=0;char ch=0; 15 while(!isdigit(ch)){w|=ch=='-';ch=getchar();} 16 while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); 17 return w?-X:X; 18 } 19 /*------------------------------------------------------------------------*/ 20 const int maxn=1e4+10; 21 vector<int>G[maxn]; 22 int du[maxn]; 23 int n,m; 24 queue<int>q; 25 int ans[maxn]; 26 void init(){ 27 for(int i=1;i<=n;++i){ 28 G[i].clear(); 29 du[i]=0; 30 ans[i]=0; 31 } 32 while(!q.empty())q.pop(); 33 34 } 35 int main( ) 36 { 37 ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); 38 //freopen("a.txt","r",stdin); 39 //freopen("a.txt","w",stdout); 40 41 //cin>>n>>m; 42 43 while(cin>>n>>m){ 44 45 init(); 46 for(int i=1;i<=m;++i){ 47 int u,v; 48 cin>>u>>v; 49 50 G[v].push_back(u); 51 du[u]++; 52 } 53 54 for(int i=1;i<=n;++i)if(!du[i])q.push(i);//度为0入队 55 56 while(!q.empty()){ 57 58 int now=q.front();q.pop(); 59 //ans[] 60 for(int i=0;i<G[now].size();++i){ 61 int temp=G[now][i]; 62 du[temp]--; 63 ans[temp]=max(ans[now]+1,ans[temp]); 64 if(du[temp]==0) 65 q.push(temp); 66 } 67 } 68 int flag=0; 69 for(int i=1;i<=n;++i){ 70 if(du[i]) 71 flag=1; 72 break; 73 } 74 75 if(!flag){ 76 int res=n*888; 77 for(int i=1;i<=n;++i)res+=ans[i]; 78 cout<<res<<endl; 79 }//cout<<(n*888+n-1)<<endl; 80 else cout<<-1<<endl; 81 } 82 83 84 return 0; 85 }