l1算的应该是没问题的。因为和题解对了一下l1相同而且WA的都是k=2的情况。但是l2就总是正解差1,差2的样子 问题应该在于dp()或者说修改边权为-1的操作上。但我调了快一天都调不出来。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,k,p,q,ans;
struct edge{
int to,w,flag;
};
vector<edge> g[N];
int d[N],ed,st;
bool nxt[N];
void add(int x,int y,int z)
{
g[x].push_back({y,z,-1});
}
void dfs(int x,int from)
{
//t++;
//cout<<g[x].size()<<endl;
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i].to;
//int k=g[x][i].id;
//cout<<"v:"<<v<<" from:"<<from<<endl;
if(v==from) continue;//边界
d[v]=d[x]+1;
//cout<<d[v]<<endl;
if(d[v]>d[p]) p=v;
dfs(v,x);
}
}
void dfss(int x,int from)
{
//t++;
//cout<<g[x].sizex ()<<endl;
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i].to;
//int k=g[x][i].id;
//cout<<"v:"<<v<<" from:"<<from<<endl;
if(v==from) continue;
d[v]=d[x]+1;
//cout<<d[v]<<endl;
//cout<<"x:"<<x<<" v:"<<v<<endl;
if(d[v]>d[p])
{
p=v;
g[x][i].flag=1;//标记直径经过的边
for(int j=0;j<g[v].size();j++)
{
if(g[v][j].to==x) g[v][j].flag=1;
}
}
//cout<<"p::"<<p<<endl;
//cout<<"v: "<<v<<"x: "<<x<<endl;
dfss(v,x);
}
}
void dp(int x,int from)
{
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i].to;
int w=g[x][i].w;
//cout<<w<<endl;
if(v==from) continue;
dp(v,x);
ans=max(ans,d[v]+d[x]+w);
d[x]=max(d[x],d[v]+w);
}
//ans=max(ans,d[x]);
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n-1;i++)
{
int x,y;
cin>>x>>y;
add(x,y,1);
add(y,x,1);
}
dfs(1,0);
d[p]=0;
dfss(p,0);
int t=0;
for(int i=1;i<=n;i++) //修改边权
for(int j=0;j<g[i].size();j++)
if(g[i][j].flag==1) {g[i][j].w=-1,t++;}
int l1=d[p];
//cout<<l1<<endl;
if(k==1)
{
cout<<2*(n-1)-(l1-1)<<endl;
return 0;
}
memset(d,0,sizeof(d));
dp(1,0);
int l2=ans;
//cout<<l2<<endl;
cout<<2*(n-1)-(l1-1)-(l2-1);
return 0;
}