4890: [Tjoi2017]城市

来源:互联网 发布:首都师范大学vpn端口 编辑:程序博客网 时间:2024/06/07 07:21

这题题面看这里:https://www.luogu.org/problem/show?pid=3761

这里怎么做呢

看了下数据范围。。

感觉n^2能过

那就暴力枚举删去那一条边咯

然后暴力搞一搞

至于最新的边建在哪里

肯定就是两颗子树的重心啦

至于怎么求重心,看代码吧。。

这样的话每次遍历三次树就可以得出答案了


#include<cstdio>#include<cstdlib>#include<cstring>const int N=5005;const int MAX=1<<30;struct qq{    int y,c,last;}s[N*2];int last[N];int n;int S[N],T[N],C[N];void init (int num,int x,int y,int c){    s[num].y=y;s[num].c=c;    s[num].last=last[x];    last[x]=num;}int f[N],f1[N];//子树以内的最大值    子树以外的最大值 int F[N],G[N];//次大值   最大值的位置 int mymax (int x,int y){return x>y?x:y;}int mymin (int x,int y){return x<y?x:y;}int NO;void dfs (int x,int fa)//更新f值 {    f[x]=0;    for (int u=last[x];u!=-1;u=s[u].last)    {        if (NO==u||u==NO+n-1) continue;        int y=s[u].y;        if (y==fa) continue;        dfs(y,x);        int lalal=f[y]+s[u].c;        if (f[x]<lalal)        {            F[x]=f[x];            f[x]=lalal;            G[x]=y;        }        else if (F[x]<lalal)            F[x]=lalal;    }}void dfs1 (int x,int fa){    for (int u=last[x];u!=-1;u=s[u].last)    {        if (NO==u||u==NO+n-1) continue;        int y=s[u].y;        if (y==fa) continue;        f1[y]=f1[x]+s[u].c;        if (G[x]!=y) f1[y]=mymax(f[x]+s[u].c,f1[y]);        else f1[y]=mymax(F[x]+s[u].c,f1[y]);        dfs1(y,x);    }}int tmp,tmp1;int lalal=0;void get_root (int x,int fa){    if (mymax(f[x],f1[x])<tmp) {tmp=mymax(f[x],f1[x]);tmp1=x;}    for (int u=last[x];u!=-1;u=s[u].last)    {        if (NO==u||u==NO+n-1) continue;        int y=s[u].y;        if (y==fa) continue;        get_root(y,x);    }}  int main(){    int ans=MAX;    scanf("%d",&n);    for (int u=1;u<n;u++)        scanf("%d%d%d",&S[u],&T[u],&C[u]);    memset(last,-1,sizeof(last));    for (int u=1;u<n;u++)        init(u,S[u],T[u],C[u]),init(u+n-1,T[u],S[u],C[u]);    for (int u=1;u<n;u++)//割掉哪一条边     {        memset(f,0,sizeof(f));        memset(F,0,sizeof(F));        NO=u;        dfs(S[u],0);dfs(T[u],0);        f1[S[u]]=0;dfs1(S[u],0);        f1[T[u]]=0;dfs1(T[u],0);            int xx,xx1;        int ans1=0;        tmp=MAX;get_root(S[u],0);xx=tmp1;        tmp=MAX;get_root(T[u],0);xx1=tmp1;        for (int i=1;i<=n;i++) ans1=mymax(ans1,mymax(f[i],f1[i]));        ans=mymin(ans,mymax(ans1,mymax(f[xx],f1[xx])+mymax(f[xx1],f1[xx1])+C[u]));        /*printf("%d %d %d\n",xx,f[xx],f1[xx]);        printf("%d %d %d\n",xx1,f[xx1],f1[xx1]);        system("pause");*/    }    printf("%d\n",ans);    return 0;}


原创粉丝点击