拓扑排序
注意每个点要从其所在最长路的更新他的糖果数目
那么就是每条边起点开始查找找到当前点的入度减1可以为0的点开始更新糖果,然后入度为0点入队
就是离其最近的点开始赋值,考虑入度非1,通过这个点的两条边长度不一样
注意每个点要从其所在最长路的更新他的糖果数目
那么就是每条边起点开始查找找到当前点的入度减1可以为0的点开始更新糖果,然后入度为0点入队
就是离其最近的点开始赋值,考虑入度非1,通过这个点的两条边长度不一样
另外注意判断是否存在环
#include <map>
#include <set>
#include <list>
#include <cmath>
#include<cctype>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b)
{
return a % b == 0 ? b : gcd(b, a % b);
}
#define MAXN 10005
int tmp[MAXN];
LL ans;
//bool vis[MAXN];
int N,M;
int q[MAXN];
vector <int >G[MAXN];
int inde[MAXN];
void read()
{
int a,b;
memset(inde,0,sizeof(inde));
memset(tmp,0,sizeof(tmp));
for (int i=0;i<=N;i++) G[i].clear();
for (int i=0;i<M;i++)
{
scanf("%d%d",&a,&b);
G[b].push_back(a);
inde[a]++;
}
}
bool topo()
{
memset(q,0,sizeof(q));
int res=N;
//bool flag=false;
int front=0,rear=0;
for (int i=1;i<=N;i++)
{
if (inde[i]==0)
q[rear++]=i;
}
while (front<rear)
{
res--;
int u=q[front];
//if (vis[u]) flag=true;
//vis[u]=true;
int t=tmp[u];
for (int i=0;i<(int)G[u].size();i++)
{
int v=G[u][i];
if (--inde[v]==0)//由离其最近的点来进行赋值。考虑交叉情况入度非1,两链长度不一
{
tmp[v]=t+1;
q[rear++]=v;
}
}
front++;
}
if (res>0) return false;
return true;
}
void slove()
{
ans=888*N;
if (topo())
{
for (int i=1;i<=N;i++)
ans+=tmp[i];
printf("%lld\n",ans);
}
else
printf("-1\n");
}
int main()
{
//freopen("sample.txt","r",stdin);
while (scanf("%d%d",&N,&M)!=EOF)
{
ans=0;
read();
slove();
}
return 0;
}