题目链接: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 }