您的位置:首页 > 其它

hdu2647 拓扑序

2015-09-09 15:43 253 查看
题意:年终要给 n 个员工发奖金,每个人的起始金额是888,有些人觉得自己做的比另一个人好所以应该多得一些钱,问最少需要花多少钱,如果不能满足所有员工的要求,输出 -1

拓扑排序,从奖金少的向奖金多的建边,这样从奖金少的开始可以定 888 。对所有最开始入度为 0 的点开始,全发 888 ,由于加入队列的点的奖金数额其实是从小到大的,所以当某个点入度减为 0 时,就直接用这次用来更新的点的奖金+1 作为新一个点的奖金就行。

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int maxn=1e4+5;
const int maxm=2e4+5;

int ans,n;
int id[maxn],num[maxn];
int head[maxn],point[maxm],nxt[maxm],size;

void add(int a,int b){
point[size]=b;
nxt[size]=head[a];
head[a]=size++;
id[b]++;
}

bool topo(){
ans=0;
queue<int>q;
for(int i=1;i<=n;++i)if(!id[i]){
q.push(i);
num[i]=888;
}
int cnt=0;
while(!q.empty()){
int u=q.front();q.pop();
ans+=num[u];
cnt++;
for(int i=head[u];~i;i=nxt[i]){
int j=point[i];
id[j]--;
if(!id[j]){
num[j]=num[u]+1;
q.push(j);
}
}
}
if(cnt==n)return 1;
return 0;
}

int main(){
int m;
while(scanf("%d%d",&n,&m)!=EOF){
memset(head,-1,sizeof(head));
size=0;
memset(id,0,sizeof(id));
while(m--){
int a,b;
scanf("%d%d",&a,&b);
add(b,a);
}
if(topo())printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: