hdu2647 拓扑序
2015-09-09 15:43
253 查看
题意:年终要给 n 个员工发奖金,每个人的起始金额是888,有些人觉得自己做的比另一个人好所以应该多得一些钱,问最少需要花多少钱,如果不能满足所有员工的要求,输出 -1
拓扑排序,从奖金少的向奖金多的建边,这样从奖金少的开始可以定 888 。对所有最开始入度为 0 的点开始,全发 888 ,由于加入队列的点的奖金数额其实是从小到大的,所以当某个点入度减为 0 时,就直接用这次用来更新的点的奖金+1 作为新一个点的奖金就行。
View Code
拓扑排序,从奖金少的向奖金多的建边,这样从奖金少的开始可以定 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
相关文章推荐
- FOJ 1075
- Cube and EarthDistance
- centos6.5内网搭建DNS服务器
- android 数据存取——SharedPreferences
- UILabel显示多行文本,字体设置
- 厦门烂尾楼大起底 “维权”悠着点
- java1.5之线程池
- 1099. Build A Binary Search Tree (30)
- The DOM in JavaScript
- 0909 操作系统
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 9: ordinal not in range(128)
- 深入理解计算机系统——第12章:多线程中共享变量
- UVa120 - Stacks of Flapjacks
- Spring 注解@Transactional readOnly=true
- 初识ASP.NET Mvc5+EF7的奇妙之旅
- String str = new String("abc")和String str = "abc"区别
- [Django高级]理解django中的中间件机制和执行顺序
- 学习笔记-linux中的时间管理
- Android Studio com.android.dex.DexException: Multiple dex files define(重复引用包)
- 认知更新、能力训练的三种方式