Description

The bovine population boom down on the farm has caused serious congestion on the cow trails leading to the barn. Farmer John has decided to conduct a study to find the bottlenecks in order to relieve the 'traffic jams' at milking time.

The pasture contains a network of M (1 ≤ M ≤ 50,000) one-way trails, each of which connects exactly two different intersections from the set of N (1 ≤ N ≤ 5,000) intersections conveniently numbered 1..N; the barn is at intersection number N. Each trail connects one intersection point to another intersection point with a higher number. As a result, there are no cycles and, as they say on the farm, all trails lead to the barn. A pair of intersection points might be connected by more than one trail.

During milking time rush hour, the cows start from their respective grazing locations and head to the barn. The grazing locations are exactly those intersection points with no trails connecting into them. Each cow traverses a 'path', which is defined as a sequence of trails from a grazing location to the barn.

Help FJ finding the busiest trail(s) by computing the largest number of possible paths that contain any one trail. The answer is guaranteed to fit in a signed 32-bit integer.

Input

Line 1: Two space-separated integers: N and M.
Lines 2..M+1: Two space-separated intersection points.

Output

Line 1: The maximum number of paths passing through any one trail.

Sample Input

7 7
1 3
3 4
3 5
4 6
2 3
5 6
6 7

Sample Output

4
题意:从入度为0的点到终点n中找出被线trial经过最多的path,并统计该path被经过的次数。对每条边<u,v>求出点u的入度x和v的出度y,
求出Max(x*y);
代码如下:
#include<stdio.h>
#define Max(a, b) ( a > b ? a : b)
#define MAX 5001
int graph[MAX][MAX], graph1[MAX][MAX];
int len[MAX], len1[MAX], numOfIn[MAX], numOfOut[MAX], numOfUse[MAX], numOfUse1[MAX];
void SetBase(int n)
{
    
int i;
    
for (i = 1; i <= n; i++)
    
{
        len[i] 
= 0, len1[i] = 0,numOfIn[i] = 0, numOfOut[i] = 0, numOfUse[i] = 0, numOfUse1[i] = 0;
    }

}

void SetGraph(int from, int to)
{
    graph[from][len[from]
++= to, numOfIn[to]++;
    graph1[to][len1[to]
++= from, numOfOut[from]++;
}

void TopologicalSort(int n)
{
    
int i, t, j, top = -1, k;
    
for (i = 1; i <= n; i++)
    
{
        
if (numOfIn[i] == 0)
        
{
            numOfIn[i] 
= top;
            top 
= i;
        }

    }

    
for (i = 1; i <= n; i++)
    
{
        t 
= top;
        top 
= numOfIn[top];
        
if (numOfUse[t] == 0)
        
{
            numOfUse[t] 
= 1;
        }
        
        
for (j = 0; j < len[t]; j++)
        
{
            k 
= graph[t][j];
            numOfUse[k] 
+= numOfUse[t];            
            
if (--numOfIn[k] == 0)
            
{
                numOfIn[k] 
= top;
                top 
= k;
            }

        }

    }
        
}

void TopologicalSort1(int n)
{
    
int i, t, j, top = -1, k;
    
for (i = 1; i <= n; i++)
    
{
        
if (numOfOut[i] == 0)
        
{
            numOfOut[i] 
= top;
            top 
= i;
        }

    }

    
for (i = 1; i <= n; i++)
    
{
        t 
= top;
        top 
= numOfOut[top];
        
if (numOfUse1[t] == 0)
        
{
            numOfUse1[t] 
= 1;
        }
        
        
for (j = 0; j < len1[t]; j++)
        
{
            k 
= graph1[t][j];
            numOfUse1[k] 
+= numOfUse1[t];            
            
if (--numOfOut[k] == 0)
            
{
                numOfOut[k] 
= top;
                top 
= k;
            }

        }

    }
    
}

int main()
{
    
int n, max, m, i, j, v, u, k;
    
while (scanf("%d%d"&n, &m) != EOF)
    
{
        SetBase(n);
        
for (i = 0; i < m; i++)
        
{
            scanf(
"%d%d"&v, &u);
            SetGraph(v, u);
        }

        TopologicalSort(n);
        TopologicalSort1(n);
        
for (i = 1, max = 0; i <= n; i++)
        
{
            
for (j = 0; j < len[i]; j++)
            
{    
                k 
= graph[i][j];            
                max 
= Max(max, numOfUse[i] * numOfUse1[k]);
            }

        }

        printf(
"%d\n", max);
    }

    system(
"pause");
    
return 0;
}