题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 参考思路:这道题我用的是拓扑排序。 源代码: #include <iostream> #include <vector> #include <stack> #include <algorithm> using namespace std; const int inf = 0x7fffffff; inline int myMax(int a, int b) { return a > b ? a : b; } const int MAXN = 10001; int n, m; stack<int> si;//拓扑排序用到的栈 int money[MAXN];//每个人得到的奖励数 int inDegree[MAXN];//拓扑排序中用到的每个节点的入度 vector<int> vi[MAXN];//图 int main() { while(scanf("%d%d", &n, &m)==2) { fill_n(inDegree, n+1, 0); fill_n(money, n+1, 0); while(!si.empty()) { si.pop(); } int i, j, k; for(i=1; i<=n; i++) { vi[i].clear(); } for(i=0; i<m; i++) { int u, v; scanf("%d%d", &u, &v); inDegree[u]++; vi[v].push_back(u); } j = 0;//统计入度为0的数量 for(i=1; i<=n; i++) { if(inDegree[i] == 0) { si.push(i); j++; money[i] = 888; } } vector<int>::iterator it; while(!si.empty()) { i = si.top(); si.pop(); it = vi[i].begin(); while(it != vi[i].end()) { money[*it] = myMax(money[*it], money[i] + 1); if(--inDegree[*it] == 0) { j++; si.push(*it); } it++; } } if(j != n) {//如果不等于n说明图中存在环 printf("%d\n", -1); } else { k = 0; for(i=1; i<=n; i++) { k += money[i]; } printf("%d\n", k); } } return 0; }