逆拓扑排序 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,为什么?因为存在环的话无法满足所有人的需求例如1->2,1->1,1想比2大,2想比1大,怎么可能?否则如下面思路所示

思路:可以把整张图反过来,若存在u->v,则实际上连接v->u,v的入度为0,那么我们就可以保证初始入度为0的点金额一定是888,在队列过程中,后面的点都继承前面的金额并+1,

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 using namespace std;
12 typedef long long ll; 
13 inline int read(){
14     int X=0,w=0;char ch=0;
15     while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
16     while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
17     return w?-X:X;
18 }
19 /*------------------------------------------------------------------------*/
20 const int maxn=1e4+10; 
21 vector<int>G[maxn];
22 int du[maxn];
23 int n,m;
24 queue<int>q;
25 int ans[maxn];
26 void init(){
27     for(int i=1;i<=n;++i){
28         G[i].clear();
29         du[i]=0;
30         ans[i]=0;
31     }
32     while(!q.empty())q.pop();
33     
34 }
35 int main( )
36 {    
37     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
38     //freopen("a.txt","r",stdin);
39     //freopen("a.txt","w",stdout);
40     
41     //cin>>n>>m;
42     
43     while(cin>>n>>m){
44         
45         init();
46         for(int i=1;i<=m;++i){
47             int u,v;
48             cin>>u>>v;
49             
50             G[v].push_back(u);
51             du[u]++;
52         }
53         
54         for(int i=1;i<=n;++i)if(!du[i])q.push(i);//度为0入队
55         
56         while(!q.empty()){
57             
58             int now=q.front();q.pop();
59             //ans[]
60             for(int i=0;ii){
61                 int temp=G[now][i];
62                 du[temp]--;
63                 ans[temp]=max(ans[now]+1,ans[temp]);
64                 if(du[temp]==0)
65                 q.push(temp);
66             }
67         }
68         int flag=0;
69         for(int i=1;i<=n;++i){
70             if(du[i])
71             flag=1;
72             break;
73         }
74         
75         if(!flag){
76             int res=n*888;
77             for(int i=1;i<=n;++i)res+=ans[i];
78             cout<endl;
79         }//cout<<(n*888+n-1)<
80         else cout<<-1<<endl;
81     }
82     
83     
84     return 0;
85 }

 

 

你可能感兴趣的:(逆拓扑排序 Reward HDU - 2647)