hdu 2647 (拓扑排序 邻接表建图的模板) Reward

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647

老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员工的奖金多,老板满足了所以员工的这种心思,而且老板下午发的总工资最少,问最少是多少?比如 a b 表示a的工资比b要高(高一块钱),当出现a b   b c   c a这种环的时候输出-1

拓扑排序http://www.cnblogs.com/tonghao/p/4721072.html

小指向大

邻接表建图

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 const int M = 1e4 + 10;
 9 int head[M],into[M],n,m,cas,money[M];
10 struct Edge{
11     int to;   //表示一条边上的大的结点(因为小指向大)编号
12     int next;  //表示边的编号
13 }edge[M*2];//注意为两倍
14 
15 void init()
16 {
17     for (int i=1 ; i<=n ; i++){
18         head[i]=-1;
19         into[i]=0;
20         money[i]=888;
21     }
22 }
23 
24 void addedge(int u(小),int v(大))//小指向大
25 {
26     edge[cas].to=v;   //表示第cas条边的小的结点为v
27     edge[cas].next=head[u];  //表示上一条以u为起点的边的编号,就是假设一个点有多个出度
28     head[u]=cas++;  //表示结点u所在的边的编号
29     into[v]++; //入度
30 }
31 
32 int topu()
33 {
34     queue<int>que;
35     int num=0,sum=0;
36     for (int i=1 ; i<=n ; i++)
37         if (into[i]==0)
38             que.push(i);
39     while (!que.empty()){
40         int u=que.front();
41         sum+=money[u];
42         que.pop();
43         num++;
44         for (int i=head[u] ; i!=-1 ; i=edge[i].next){
45             into[edge[i].to]--;
46             if (into[edge[i].to]==0){
47                 que.push(edge[i].to);
48                 money[edge[i].to]=money[u]+1;
49             }
50        }
51     }
52     if (num!=n) return -1;
53     return sum;
54 }
55 
56 int main()
57 {
58     while (~scanf("%d%d",&n,&m)){
59         init();
60         cas=0;
61         while (m--){
62             int a,b;
63             scanf("%d%d",&a,&b);
64             addedge(b,a);
65         }
66         printf("%d
",topu());
67     }
68     return 0;
69 }

vector建图的表示,其实差不多

 1 #include<queue>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 
 9 const int M = 1e4 + 10;
10 int a[M],into[M],money[M],n,m;
11 vector<int>q[M];
12 
13 int topu()
14 {
15     memset(into,0,sizeof(into));
16     for (int i=1 ; i<=n ; i++)
17         for (int j=0 ; j<q[i].size() ; j++)
18             into[q[i][j]]++;
19     queue<int>que;
20     int cnt=0,sum=0;
21     for (int i=1 ; i<=n ; i++)
22         if (into[i]==0)
23            que.push(i);
24     while (!que.empty()){
25         int u=que.front();
26         que.pop();
27         cnt++;
28         sum+=money[u];
29         for (int i=0 ; i<q[u].size() ; i++){
30             int v=q[u][i];
31             into[v]--;
32             if (into[v]==0) {
33                 que.push(v);
34                 money[v]=money[u]+1;
35             }
36         }
37     }
38     if (cnt!=n) return -1;
39     return sum;
40 }
41 
42 int main()
43 {
44     while (~scanf("%d%d",&n,&m)){
45         for (int i=1 ; i<=n ; i++) {
46             q[i].clear();
47             money[i]=888;
48 
49         }
50         while (m--){
51             int a,b;
52             scanf("%d%d",&a,&b);
53             q[b].push_back(a);
54         }
55         printf("%d
",topu());
56     }
57     return 0;
58 }
原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5651086.html