http://acm.hdu.edu.cn/showproblem.php?pid=2647
题意:
输入N和M代表N个人和M组数据,M组数据中的A和B代表A的工资要比B的工资高,底薪是(888元),问你这个老板至少要付
多少钱给这些员工,A比B工资高就是说A的工资“至少”比B高1元,当拓扑排序出现环的时候输出 -1 ,否则输出老板要给的钱数。
坑爹:
用拓扑排序找到入度为0的所有的点都有着同样的工资。
例如:1-2 3-4 这样1和3都为889元,2和4为888元,所以老板所付的总工资为3554元。
解法:
在每次调用cut函数的时候都要访问与他相邻的边的点的入度,每访问一次IN[ map[ k ][ i ] ] --;我们可以在每次判断一下当前的点(k)
的工资+1与map[ k ][ i ] 的工资的比较大小,取大的一个放入map[ k ][ i ] 的工资里,因为某个人可能在某条线路上工资排名可能是第二,
但在另一条线路上工资排名可能就是排第三了,根据题意,所以这个人的工资为890而不是889。
例如:

这样的话1和2为888,3为889,4为890,5为891。
View Code
1 #include<iostream>
2 #include<vector>
3 using namespace std;
4
5 const int maxn = 10000 + 10;
6 int IN[maxn];
7 int used[maxn];
8 int valve[maxn];
9 vector <int> map[maxn];
10 int N;
11
12 int find_zero()
13 {
14 int i;
15 for(i=1; i<=N; i++)
16 {
17 if(!used[i] && IN[i]==0)
18 {
19 return i;
20 }
21 }
22 return -1;
23 }
24
25 void cut(int k)
26 {
27 int i;
28 for(i=0; i<map[k].size(); i++)
29 {
30 IN[map[k][i]]--;
31 if(valve[map[k][i]]<valve[k]+1)
32 {
33 valve[map[k][i]]=valve[k]+1;
34 }
35 }
36 map[k].clear();
37 }
38
39 int topology()
40 {
41 int i;
42 int k=0;
43 int flag=0;
44 int sum=0;
45 for(i=1; i<=N; i++)
46 {
47 k=find_zero();
48 if(k==-1)
49 {
50 return -1;
51 }
52 else
53 {
54 cut(k);
55 used[k]=1;
56 sum+=valve[k];
57 }
58 }
59 return sum;
60 }
61
62 int main()
63 {
64 int M;
65 while(cin>>N>>M)
66 {
67 memset(used,0,sizeof(used));
68 memset(IN,0,sizeof(IN));
69 int i;
70 for(i=0; i<=N; i++)
71 {
72 valve[i]=888;
73 }
74
75 for(i=1; i<=M; i++)
76 {
77 int a;
78 int b;
79 cin>>a>>b;
80 map[b].push_back(a);
81 IN[a]++;
82 }
83
84 int sum=topology();
85 if(sum!=-1)
86 {
87 cout<<sum<<endl;
88 }
89 else
90 {
91 cout<<-1<<endl;
92 }
93 for(i=1; i<=N; i++)
94 {
95 map[i].clear();
96 }
97 }
98 return 0;
99 }
来源:https://www.cnblogs.com/pcpcpc/archive/2012/09/10/2678461.html
