逆拓扑排序 Reward HDU - 2647

Reward

 HDU - 2647 

题意:每个人的起始金额是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,

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll; 
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
/*------------------------------------------------------------------------*/
const int maxn=1e4+10; 
vectorG[maxn];
int du[maxn];
int n,m;
queueq;
int ans[maxn];
void init(){
	for(int i=1;i<=n;++i){
		G[i].clear();
		du[i]=0;
		ans[i]=0;
	}
	while(!q.empty())q.pop();
	
}
int main( )
{	
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    //freopen("a.txt","r",stdin);
    //freopen("a.txt","w",stdout);
    
    //cin>>n>>m;
    
    while(cin>>n>>m){
    	
    	init();
    	for(int i=1;i<=m;++i){
	    	int u,v;
	    	cin>>u>>v;
	    	
	    	G[v].push_back(u);
	    	du[u]++;
	    }
	    
	    for(int i=1;i<=n;++i)if(!du[i])q.push(i);//度为0入队
		
		while(!q.empty()){
			
			int now=q.front();q.pop();
			//ans[]
			for(int i=0;i

 

你可能感兴趣的:(拓扑排序)