RewardTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12986 Accepted Submission(s): 4143 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards.
Input One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000)
Output For every case ,print the least money dandelion 's uncle needs to distribute .If it's impossible to fulfill all the works' demands ,print -1.
Sample Input 2 1 1 2 2 2 1 2 2 1
Sample Output 1777 -1
Author dandelion
Source
Recommend yifenfei | We have carefully selected several similar problems for you: 1285 3342 1811 2680 2112
| ||
|
题目大意:要发工资了,每一个员工都要不同的要求,每一个员工都要比自己认为的后面的那一位拿的多,并且基本工资为888元,问老板最少发多少工资。
思路:用链式前向星反向构图,在用一个数组记录每一个人的工资,把入度为0的点的工资为888元,在他们后面的依次多一元,然后逐渐叠加。
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=100010;
int n,m,top,cnt;
int head[MAXN];
int a[MAXN],deg[MAXN];
long long ans[MAXN];//ans用来记录每一个人的钱数
struct node{
int to,next;
}edge[MAXN*2];
void addEdge(int u,int v){
edge[++top].to=v;
edge[top].next=head[u];
head[u]=top;
deg[v]++;
}
void topsort(){
queue<int> qu;
for(int i=1;i<=n;i++){
if(deg[i]==0){
qu.push(i);
ans[i]=888;
}
}
while(!qu.empty()){
int x=qu.front();qu.pop();
a[++cnt]=x;
for(int i=head[x];i!=-1;i=edge[i].next){
int y=edge[i].to;
if(--deg[y]==0){
qu.push(y);
ans[y]=ans[x]+1;
}
}
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
int a,b;
memset(head,-1,sizeof(head));
memset(ans,0,sizeof(ans));
memset(deg,0,sizeof(deg));
cnt=0,top=0;
for(int i=1;i<=m;i++){
scanf("%d %d",&a,&b);
addEdge(b,a);
}
topsort();
long long sum=0;
for(int i=1;i<=n;i++){
sum=sum+ans[i];
}
if(cnt==n) printf("%lld\n",sum);
else printf("-1\n");
}
return 0;
}