这道题考虑的工资应该是叠加形式,也就是从小到大的进行累加
先考虑小工资的,再依次累加成为大工资的,反之我们无法通过大工资递推到小工资
因此用到了反向建图的拓扑排序,依次把小工资的取出来(注意别用优先队列,尴尬),同时考虑到即使是大工资也有两种可能的情况
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int ind[10005];
int val[10005];
vector<int> V[10005];
int n, m;
void init()
{
memset(ind, 0, sizeof(ind));
memset(val, 0, sizeof(val));
for(int i = 1; i <= n; i ++)
V[i].clear();
}
void topo()
{
queue<int> q;
for(int i = 1; i <= n; i ++)
if(! ind[i])
{
q.push(i);
}
int cnt = 0;
while(! q.empty())
{
int h = q.front();
q.pop();
cnt ++;
for(int i = 0; i < V[h].size(); i ++)
{
int e = V[h][i];
ind[e] --;
if(! ind[e]){
q.push(e);
//cout<<val[e]<<' '<<val[h] + 1<<endl;
val[e] = max(val[e], val[h] + 1);
//cout<<val[e]<<' '<<val[h] + 1<<endl;
}
}
}
int ans1 = 0;
for(int i = 1; i <= n; i ++) ans1 += val[i];
if(cnt == n) printf("%d\n", 888*n + ans1);
else printf("-1\n");
}
int main()
{
while(scanf("%d%d",&n,&m) != EOF)
{
init();
int u, v;
for(int i = 1; i <= m; i ++)
{
scanf("%d%d",&u,&v);
V[v].push_back(u);
ind[u] ++;
}
topo();
}
return 0;
}