zuccoj1450

来源:互联网 发布:新手淘宝卖家qq交流群 编辑:程序博客网 时间:2024/05/19 11:36

Description

给你一张有向图,求出图中最长链的长度。如果图中存在环,那么我们认为链的长度是无限的。

链的定义是这样:如果A点能走到B点。那么所有从A点出发走到B点的路径都被认为是以A为始端,B为终端的链。链的长度为路径上顶点的数目(包括端点)。

Input

多组测试数据。

第一行输入n,m表示图的顶点数量与边的数量。(1<=n<=100000,0<=m<=100000)

接下来m行,每行输入x,y。表示xy有一条有向边(1<=x,y<=n, x!=y)。

Output

输出所求答案。无限长输出INF

Sample Input

5 4
1 2
2 3
2 4
4 5
2 2
1 2
2 1

Sample Output

4
INF

HINT

Source

Guo Zehui


分析:

这题主要是判断是否成环,不成环的情况就直接输出最长路即可

而判断是否成环这里要用到topsort(拓扑排序)

拓扑排序方法如下:
(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

可以每一次删除后让步数加1,然后把步数和顶点个数是否相等来判断是否成环

在dp[u]=max(dp[u],dp[x]+1)这里,因为可能有多个点连向u。

code:

#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>using namespace std;queue <int> mm;#define maxn 100005int Max(int x,int y){    if(x>y)        return x;    return y;}int outdu[maxn],p[maxn],eid,step,n,dp[maxn];struct s{    int to,next;}a[maxn*2];void init(){    int i;    memset(outdu,0,sizeof(outdu));    memset(p,-1,sizeof(p));    step=0;    eid=0;    for(i=1;i<=n;i++)        dp[i]=1;    while(!mm.empty())        mm.pop();}void ljb(int from,int to){    a[eid].to=to;    a[eid].next=p[from];    p[from]=eid++;}void bfs(){    int v,u,x,i;    while(!mm.empty())    {        x=mm.front();        mm.pop();        for(v=p[x];v!=-1;v=a[v].next)        {            u=a[v].to;            outdu[u]--;            if(outdu[u]==0){                step++;                outdu[u]--;                mm.push(u);            }            dp[u]=Max(dp[u],dp[x]+1);        }    }}int main(){    int m,x,y,i,ma;    while(~scanf("%d%d",&n,&m))    {        init();        while(m--){            scanf("%d%d",&x,&y);            outdu[y]++;            ljb(x,y);        }        for(i=1;i<=n;i++){            if(outdu[i]==0){                step++;                outdu[i]--;                mm.push(i);            }        }        bfs();        if(step!=n)            printf("INF\n");        else{            ma=dp[1];            for(i=2;i<=n;i++)                if(dp[i]>ma)                    ma=dp[i];            printf("%d\n",ma);        }    }    return 0;}/**************************************************************    Problem: 1450    User: 31201128    Language: C++    Result: Accepted    Time:280 ms    Memory:3736 kb****************************************************************/