传送门
题目描述
链接里面都有我就不说了
分析
首先一个毛毛虫,就是一条主链,外加上主链上所有点所直接连接的点
我们用f[u]表示以u为顶点时形成的最大的毛毛虫,那么我们需要找到和u相连的点v,找到最大的f[v],容易写出状态转移方程
f[u] = f[v] + 1 + max(0,cnt - 1);
cnt是与u直接相连的点
这个状态转移方程应该比较好理解,加上自己这个点,再加上其他没有出现在最大子毛毛虫中的直接相连的点即可
然后只需要维护每一个点作为顶点时产生的最大毛毛虫以及次大毛毛虫即可
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 3000010;
int h[N],e[N * 2],ne[N * 2],idx;
int f[N];
int n,m;
int ans;
void add(int x,int y){
ne[idx] = h[x],e[idx] = y,h[x] = idx++;
}
void dfs(int u,int fa){
int max1 = 0,max2 = 0;
int cnt = 0;
for(int i = h[u];~i;i = ne[i]){
int j = e[i];
cnt++;
if(j == fa) continue;
dfs(j,u);
f[u] = max(f[u],f[j]);
if(f[j] > max1) max2 = max1,max1 = f[j];
else if(f[j] > max2) max2 = f[j];
}
cnt--;
f[u] += (1 + max(0,cnt - 1));
ans = max(ans,f[u] + max2);
}
int main(){
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
dfs(1,-1);
printf("%d\n",max(ans,1));
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/