题意:给出n个点是m条无向边,假设一条链长度是p,且这条链上的点是严格递增的,链的末端端点为u,求出最大的degree[u]*p
思路:dp[i]代表以i结尾的链的最大长度(不包括i本身),那么我们对点输入的时候辩证一下顺序,然后对起点进行排序,最后答案就是(dp[i]+1)*degree[i]
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
const int qq = 200000+10;
int dp[qq/2];
int degree[qq/2];
struct Edge{
int u,v;
bool operator < (const Edge &a)const{
if(a.u==u) return v<a.v;
return u<a.u;
}
}edge[qq];
int main(){
int n,m;scanf("%d%d",&n,&m);
memset(degree, 0, sizeof(degree));
for(int i=0; i<m; ++i){
scanf("%d%d",&edge[i].u,&edge[i].v);
degree[edge[i].u]++,degree[edge[i].v]++;
if(edge[i].u>edge[i].v) swap(edge[i].u, edge[i].v);
}
sort(edge, edge+m);
memset(dp, 0, sizeof(dp));
for(int i=0; i<m; ++i){
int u=edge[i].u,v=edge[i].v;
dp[v]=max(dp[v], dp[u]+1);
}
ll res=0;
for(int i=1; i<=n; ++i)
res=max(res, (ll)(dp[i]+1)*degree[i]);
printf("%lld\n", res);
return 0;
}