链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647
Sample Input
2 1
1 2
2 2
1 2
2 1
Sample Output
1777
-1
题意:老板要发工资,但一些员工有自己的小算盘,并向老板提了出来,员工a和b,a的工资要比b的工资高。老板想尽量满足员工的要求,并且使自己支付的总金额最少。每个人的最低工资为888。(这老板可真是够扣的,建议员工集体罢工)
解题思路:首先老板想要满足提出要求的员工的要求(因为有些员工并没有要求(这样的员工老板最喜欢了))。老板要满足所有要求就要保证这些要求不冲突,如果要求不冲突,这像极了拓扑排序(离散中有)中的不成环。如果成环,则说明要求冲突,不成环则说明不冲突。不了解拓扑排序的不要紧,看看代码就明白了。
Code:
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 20005;
int n,m,in[maxn],a[maxn];
vector<int>v[maxn];
int main(){
while(cin>>n>>m){
int sum=0;
memset(in,0,sizeof(in));
memset(a,0,sizeof(a));//
for(int i=1;i<=n;i++) a[i]=888;// 使每个员工的初始工资为888
sum=888*n;//
for(int i=1;i<=n;i++) v[i].clear();
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
in[x]++;
v[y].push_back(x);//构图
}
queue<int>q;
for(int i=1;i<=n;i++){
if(in[i]==0){
q.push(i);//将入度为0的点入队
}
}
while(!q.empty()){
int xx = q.front();
q.pop();
n--;//将入度为0的点剔除,如果不成环,最后n==0
for(int i=0;i<v[xx].size();i++){
int yy = v[xx][i];//
if(a[xx]>=a[yy]){//满足每个员工的要求
int temp=a[yy];//
a[yy]=a[xx]+1;//
sum+=(a[yy]-temp);//
}//除去这些画了双杠的行,其他的基本就是拓扑排序的模板
in[v[xx][i]]--;//删边
if(in[v[xx][i]]==0){
q.push(v[xx][i]);
}
}
}
//cout<<n<<endl;
if(n) cout<<"-1
";
else cout<<sum<<endl;
}
return 0;
}