CodeForces 615 B. Longtail Hedgehog(dp)

Description
给一张n个点m条边的无向图,对于一条点编号递增的链,设其链未点的度为degree,链长为len,那么这条链的美丽值为beauty=len*degree,问这张图上所有编号递增的链中的最大美丽值
Input
第一行为两个整数n和m表示点数和边数,之后m行每行两个整数u和v表示这张图上u点和v点间有边,保证无重边无自环(2<=n<=100000,1<=m<=200000)
Output
输出编号递增的链的最大美丽值
Sample Input
8 6
4 5
3 5
2 5
1 2
2 8
6 7
Sample Output
9
Solution
每个点的度数很好求,问题在于如何求以某个点结尾的编号递增的最长链的长度,设dp[v]为以点v为结尾的编号递增的链的长度最大值,那么我们有dp[v]=max(dp[v],dp[u]+1),其中u为所有和v相连的点中编号比v小的,那么这样就可以在O(m)的时间内得到所有点的dp值,从中找到dp[i]*degree[i]的最大值即为答案
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 222222
typedef long long ll;
struct node
{
    int u,v;
}edge[maxn];
int n,m,degree[maxn],dp[maxn];
int cmp(node a,node b)
{
    if(a.u==b.u)return a.v<b.v;
    return a.u<b.u;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(degree,0,sizeof(degree));
        memset(dp,0,sizeof(dp));
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            degree[u]++,degree[v]++;
            if(u>v)swap(u,v);
            edge[i].u=u,edge[i].v=v;
        }
        sort(edge,edge+m,cmp);
        for(int i=0;i<m;i++)
            dp[edge[i].v]=max(dp[edge[i].v],dp[edge[i].u]+1);
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans=max(ans,1ll*(dp[i]+1)*degree[i]);
        printf("%I64d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(CodeForces 615 B. Longtail Hedgehog(dp))