hdu 2647(拓扑排序)

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

思路:就是一个简单的拓扑排序,给每个节点标号,不过要注意的是访问过的节点的id应该取最大才能满足要求,然后就是要反向建边(这里wa了好多次)。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 using namespace std;
 8 #define MAXN 10010
 9 typedef pair<int,int>Pair;
10 vector<int>map[MAXN];
11 struct Point {
12     int id;
13 } point[MAXN];
14 int from[MAXN];
15 int n,m,ans,cnt;
16 
17 bool Solve() {
18     queue<Pair>Q;
19     cnt=0;
20     for(int i=1; i<=n; i++) {
21         if(from[i]==0) {
22             Q.push(make_pair(i,0));
23             cnt++;
24         }
25     }
26     while(!Q.empty()) {
27         Pair pp=Q.front();
28         Q.pop();
29         int u=pp.first,id=pp.second;
30         for(int i=0; i<map[u].size(); i++) {
31             int v=map[u][i];
32             point[v].id=max(id+1,point[v].id);
33             from[v]--;
34             if(from[v]==0) {
35                 Q.push(make_pair(v,point[v].id));
36                 cnt++;
37             }
38         }
39     }
40     if(cnt==n)return true;
41     return false;
42 }
43 
44 
45 int main() {
46 //   freopen("1.txt","r",stdin);
47     int u,v;
48     while(~scanf("%d%d",&n,&m)) {
49         for(int i=1; i<=n; i++) {
50             point[i].id=0;
51             map[i].clear();
52         }
53         memset(from,0,sizeof(from));
54         while(m--) {
55             scanf("%d%d",&u,&v);
56             map[v].push_back(u);//反向的,wa了好多次
57             from[u]++;
58         }
59         if(Solve()) {
60             ans=0;
61             for(int i=1; i<=n; i++)ans+=point[i].id;
62             ans+=888*n;
63             printf("%d\n",ans);
64         } else
65             puts("-1");
66     }
67     return 0;
68 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3122746.html