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

 

你可能感兴趣的:(HDU)