POJ-1985 Cow Marathon
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
#define MAXN 100005
struct node{
int x,y,z;
}path[MAXN<<1];
vector<int> pv[MAXN];
void add(int x,int y,int z,int i){
path[i-1<<1]=node{x,y,z};pv[x].push_back(i-1<<1);
path[i-1<<1|1]=node{y,x,z};pv[y].push_back(i-1<<1|1);
}
int best,mx;
void dfs(int cur,int f,int len){
if(mx<len){
mx=len;
best=cur;
}
for(int i=0;i<pv[cur].size();i++){
int to=path[pv[cur][i]].y;
if(to==f)continue;
dfs(to,cur,len+path[pv[cur][i]].z);
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y,z;
char c;
scanf("%d%d%d %c",&x,&y,&z,&c);
add(x,y,z,i);
}
dfs(1,-1,0);
dfs(best,-1,0);
cout<<mx<<endl;
return 0;
}
牛客2019多校赛第四场 A-meeting
bfs
#include<bits/stdc++.h>
using namespace std;
vector<int> path[100005];
int book[100005];
int best;
int ans;
int dep[100005];
void bfs(int first){
memset(dep,0,sizeof(dep));
queue<int> que;
que.push(first);
while(!que.empty()){
int cur=que.front();
que.pop();
if(book[cur]==1&&ans<dep[cur]){
ans=dep[cur];
best=cur;
}
for(int i=0;i<path[cur].size();i++){
int to=path[cur][i];
if(dep[to]==0){
que.push(to);
dep[to]=dep[cur]+1;
}
}
}
}
int main(){
int n,m;
while(cin>>m>>n){
for(int i=1;i<=m;i++)path[i].clear();
for(int i=1;i<m;i++){
int x,y;
cin>>x>>y;
path[x].push_back(y);
path[y].push_back(x);
}
int first=0;
for(int i=1;i<=n;i++){
int t;
cin>>t;
book[t]=1;
first=t;
}
bfs(first);
bfs(best);
cout<<(ans-1)/2+1<<endl;
}
return 0;
}
树形dp
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
struct node{
int x,y;
}path[MAXN<<1];
vector<int> pv[MAXN];
void add(int x,int y,int i){
path[i-1<<1]=node{x,y};pv[x].push_back(i-1<<1);
path[i-1<<1|1]=node{y,x};pv[y].push_back(i-1<<1|1);
}
int from[MAXN];
int dp[MAXN][2];
int book[MAXN];
int son[MAXN];
void dfs(int cur,int f){
son[cur]=book[cur];
for(int i=0;i<pv[cur].size();i++){
int to=path[pv[cur][i]].y;
if(to==f)continue;
dfs(to,cur);
son[cur]+=son[to];
if(!son[to])continue;//之后的路径上都没有被标记的点 直接跳过
if(dp[cur][0]<dp[to][0]+1){
from[cur]=to;//标记最大路径上的点
dp[cur][1]=dp[cur][0];
dp[cur][0]=dp[to][0]+1;//更新次大和最大值
}
else if(dp[cur][1]<dp[to][0]+1){
dp[cur][1]=dp[to][0]+1;
}
}
}
int ans;
void dp_tree(int cur,int f,int len){
ans=min(ans,max(len,dp[cur][0]));
for(int i=0;i<pv[cur].size();i++){
int to=path[pv[cur][i]].y;
if(to==f)continue;
if(!son[to])continue;
if(from[cur]==to){//在最长路上
dp_tree(to,cur,max(len,dp[cur][1])+1);
}
else {
dp_tree(to,cur,max(len,dp[cur][0])+1);
}
}
}
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y,i);
}
for(int i=1;i<=k;i++){
int t;
scanf("%d",&t);
book[t]=1;
}
dfs(1,-1);
ans=n;
dp_tree(1,-1,0);
cout<<ans;
return 0;
}