http://codeforces.com/contest/615/problem/B
题意 给你一个图,不一定联通
n=1e5,m=2e5
符合题意的一条路 是 从头到尾 每个节点都是递增的。 如 1 - 2 -5合法 1 - 5 -4不合法
求最大的ans值 ,ans值等于某条合法路径的节点数 乘上 【整个图】 与末尾端点的连接的点的个数 如 1- 2 -5 ,如果5共有3个点与其相连,那么这条路的ans=3*3=9;
直接dfs肯定会超时啦。
我们只需要求出 以每个节点 为【末尾端点】时,所在路径的长度,然后ans值就可以直接得到了
在dfs过程中 用个dp数组,dp[x]记录点x为结束端点的时候 所在路径长度。
注意,如果dfs是按 递增的顺序走的话,不好得到以x为结束端点的长度,我们可以 反过来玩,按递减的顺序走,得到的dp[x]便是我们所要的了。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <stack> #include <vector> #include <iostream> using namespace std; __int64 min(__int64 a,__int64 b){return a<b?a:b;} __int64 max(__int64 a,__int64 b){return a>b?a:b;} vector<__int64> tm[100005]; __int64 dp[200005]; __int64 dfs(__int64 x ) { if (dp[x]) return dp[x]; dp[x]=1; for(__int64 i=0;i<tm[x].size();i++) { if (tm[x][i]>x)continue; //递减地走 dp[x]=max(dp[x],dfs(tm[x][i])+1); } return dp[x]; } int main() { __int64 i,j,k; __int64 n,m; __int64 tmp,tt; __int64 t1,t2; scanf("%I64d%I64d",&n,&m); for (i=1;i<=m;i++) { scanf("%I64d%I64d",&t1,&t2); tm[t1].push_back(t2); tm[t2].push_back(t1); } __int64 maxx=0; for(i=1;i<=n;i++) { maxx=max(maxx,dfs(i )*tm[i].size()); } printf("%I64d\n",maxx); return 0; }