统计各结点出度,出度为0的点表示他们(A类)所需的reward为888,而reward要比他们多的(B类)则为888+1,reward要比B类多的(C类)则为888+2.。。。
其中若一开始从A类得到了B类,然后有某个B类要比另一个B类的reward多,则该B类的reward从888+1改为888+2.。。。
以此类推,采用逆向拓扑排序可解此题
#include <cstdio>
#include <cstring>
#include <vector>
#define MAX 10005
using namespace std;
vector <int> map[MAX];
int out[MAX],cnt,vis[MAX],add[MAX];
void update(int v,int a)
{
if(!vis[v])
cnt++;
vis[v]=1;
for(unsigned i=0;i<map[v].size();i++)
{
if(a>add[map[v][i]])
add[map[v][i]]=a;
update(map[v][i],a+1);
}
}
bool repeat(int u,int v)
{
for(unsigned i=0;i<map[v].size();i++)
if(map[v][i]==u)
return true;
return false;
}
void solve(int n,int m)
{
for(int i=1;i<=n;i++)
map[i].clear();
memset(out,0,sizeof(out));
memset(vis,0,sizeof(vis));
int u,v;
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
if(!repeat(u,v))
{
map[v].push_back(u);
out[u]++;
}
}
cnt=0;
memset(add,0,sizeof(add));
for(int i=1;i<=n;i++)
if(!out[i])
update(i,1);
if(cnt==n)
{
int res=0;
for(int i=1;i<=n;i++)
res+=add[i];
printf("%d\n",res+n*888);
}
else
printf("-1\n");
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)>0)
solve(n,m);
}