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 }