链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 , 不算复杂的拓扑排序。
这道题不复杂,有一点需要考虑的就是当前保存在队列首的顶点的边删去时,会产生新的入度为0的顶点,这时产生的新的入度为0的顶点要比队列首的顶点要高一级,就是工资比他多1,这点处理就没什么事情了。
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = 2333333;
const int maxn = 10000 + 5;
int Rank[maxn] , degree[maxn];
vector <int> graph[maxn];
int n , m;
bool toposort()
{
int i , j , u , v , tot;
tot = 0;
memset(Rank , 0 , sizeof(Rank));
memset(degree , 0 , sizeof(degree));
for(int i = 1 ; i <= n ; i++)
for(int j = 0 ; j < graph[i].size() ; j++)
degree[ graph[i][j] ] ++;
queue <int> que;
for(int i = 1 ; i <= n ; i++) {
if(degree[i] == 0) {
que.push(i);
Rank[i] = 0;
tot++;
}
}
while(!que.empty()) {
int u = que.front();
que.pop();
for(int i = 0 ; i < graph[u].size() ; i++) {
int tmp = graph[u][i];
degree[tmp]--;
if(degree[tmp] == 0) {
que.push(tmp);
Rank[tmp] = Rank[u] + 1; //就是这里,工资要多1
tot++;
}
}
}
return tot == n;
}
int main()
{
int a , b;
while(~scanf("%d %d" , &n , &m))
{
for(int i = 1 ; i <= n ; i++)
graph[i].clear();
while(m--) {
scanf("%d %d" , &a , &b);
graph[b].push_back(a);
}
if(toposort()) {
int res = 888 * n;
for(int i = 1 ; i <= n ; i++)
res += Rank[i];
printf("%d
" , res);
} else {
printf("-1
");
}
}
return 0;
}