CF 592D(Super M-虚树直径)

来源:互联网 发布:淘宝官网网站首页 编辑:程序博客网 时间:2024/05/22 14:23

给定一棵树,找一条路,要求经过指定的树上k个点,使路程最小
求起点最小编号,与路程

我们把树的无用点扔掉,剩下虚树,
要经过它的每一个点,则起点s,终点t,路程显然为2mdiss,t(m=)
现在要求max(diss,t),就是树的直径(怎么开心怎么求)。

寻找编号最小点:
由于树的直径必然会经过树的重心,求出树的重心并找到离他最远的点中编号最小的s。
(有可能是次远点,所以从s点再dfs一遍找离他最远的点中编号最小的)

#include<bits/stdc++.h>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define pb push_back#define mp make_pair #define fi first#define se secondtypedef long long ll;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} #define MAXN (123456+10)vector<int> To[MAXN];int n,m;int a[MAXN];bool b[MAXN]={0}; void dfs(int x,int fa) {    int siz=To[x].size();    Rep(i,siz) {        int v=To[x][i];        if (v==fa) continue;        dfs(v,x);        if (b[v] && !b[x]) b[x]=1,a[++m]=x;    }}int son[MAXN]={0},h[MAXN]={0};void dfs2(int x,int fa) {    son[x]=1;    for(int v:To[x]) {        if ((!b[v])||v==fa) continue;        dfs2(v,x);        h[x]=max(h[x],son[v]);        son[x]+=son[v];    }    h[x]=max(h[x],m-son[x]);}int md=0,d[MAXN];void dfs3(int x,int fa) {    if (d[x]>md) md=d[x];    for(int v:To[x]) {        if ((!b[v])||v==fa) continue;        d[v]=d[x]+1;         dfs3(v,x);    }}int main(){//  freopen("CF592D.in","r",stdin);//  freopen(".out","w",stdout);    n=read(),m=read();    For(i,n-1) {        int a=read(),b=read();        To[a].pb(b);        To[b].pb(a);    }    For(i,m) {        a[i]=read();        b[a[i]]=1;    }    dfs(a[1],0);    dfs2(a[1],0);    int pa=a[1];    Fork(i,2,m) {        if (h[pa]>h[a[i]]) {            pa=a[i];        }    }    d[pa]=1;dfs3(pa,0);    int ans=INF;        For(i,m) {        if (d[a[i]]==md) ans=min(ans,a[i]);    }    int ans2=INF;    d[ans]=1;dfs3(ans,0);    For(i,m) {        if (d[a[i]]==md) ans2=min(ans2,a[i]);    }    cout<<min(ans,ans2)<<endl<<2*(m-1)-md+1<<endl;     return 0;}
0 0
原创粉丝点击