統計各結點出度,出度爲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);
}