题意
给出一棵大小为N(<=5e5)的树,求树上两条边不相交路径能把这棵树分成的联通块个数的最大值。
背景
在年底之前改完了一道今年省选题xd
庆幸这道题出在了我只会暴力的时候…
以及,像上次那个寿司餐厅一样,我凭着大半年前的记忆去做这道题,于是又审错了题,写了一个边可以相交的东西…(好在变成边不相交只需要稍微删几个状转
题解
这个好像并不能用语言很好地描述…
放个图好了ww
代码
其实写起来比想象中要短一些呢
//这个是压行压得不太狠的版本…在bz上是交了一个压到1400+b的
#include<bits/stdc++.h>
#define N 500005
#define mn(x,y) if(x<y)x=y
using namespace std;
int T,op,n,j,d[N][4],deg[N],ans,
to[N<<1],hd[N<<1],lk[N],cnt;
bool vis[N];
void dfs(int k)
{
d[k][0]=d[k][2]=d[k][3]=deg[k];
d[k][1]=vis[k]=1;
int m=0;
for(int x,i=lk[k];i;i=hd[i])
if(!vis[x=to[i]])
{
dfs(x);
mn(ans,d[k][3]+d[x][0]-(k==1));
mn(ans,d[k][0]+d[x][3]-(k==1));
mn(ans,d[k][1]+d[x][2]);
mn(ans,d[k][1]+d[x][1]-1);
mn(ans,d[k][2]+d[x][1]-(k==1));
mn(ans,d[k][2]+d[x][2]-(k==1));
mn(d[k][1],d[x][1]);
mn(d[k][1],d[x][2]+1);
mn(d[k][3],d[k][0]+d[x][2]-1);
mn(d[k][3],d[k][2]+d[x][0]-1);
mn(d[k][3],d[x][3]+deg[k]-1);
mn(d[k][3],d[x][0]+m+deg[k]-2);
mn(d[k][3],d[k][0]+d[x][1]-1);
mn(d[k][2],d[k][0]+d[x][0]-1);
mn(d[k][0],d[x][0]+deg[k]-1);
mn(d[k][2],d[k][0]);
mn(d[k][3],d[k][2]);
mn(m,d[x][1]);mn(m,d[x][2]);
}
deg[k]=lk[k]=vis[k]=0;
}
inline void add(int u,int v)
{to[++cnt]=v,hd[cnt]=lk[u],lk[u]=cnt,deg[u]++;}
int u,v;
char ch;
inline void rd(int &x)
{
x=0;
do ch=getchar();
while(ch<'0'||ch>'9');
do x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
while(ch>='0'&&ch<='9');
}
int main()
{
rd(T),rd(op);
while(T--)
{
rd(n);
for(int i=0;i<op;i++)
rd(u),rd(u);
for(int i=2;i<=n;i++)
rd(u),rd(v),add(u,v),add(v,u),deg[i]--;
dfs(1),printf("%d\n",ans);
cnt=ans=0;
}
}