bzoj 3124: [Sdoi2013]直径

  1 #include<cstdio>
  2 #include<iostream>
  3 #define M 400009
  4 #define ll long long
  5 using namespace std;
  6 ll d[M],v[M],ans1;
  7 int n,cnt=1,head[M],next[M],u[M],mx,f[M],q[M],ans,mx1,fro[M],from[M],sum[M]; 
  8 void jia(int a1,int a2,int a3)
  9 {
 10     cnt++;
 11     from[cnt]=a1;
 12     next[cnt]=head[a1];
 13     head[a1]=cnt;
 14     u[cnt]=a2;
 15     v[cnt]=(ll)(a3)*(ll)(n);
 16     return;
 17 }
 18 void bfs(int a1)
 19 {
 20     d[a1]=0;
 21     int h=0,t=1;
 22     q[1]=a1;
 23     f[a1]=1;
 24     fro[a1]=0;
 25     sum[a1]=0;
 26     for(;h<t;)
 27       {
 28         int p=q[++h];
 29         for(int i=head[p];i;i=next[i])
 30           if(!f[u[i]])
 31             {
 32                 f[u[i]]=1;
 33                 q[++t]=u[i];
 34                 d[u[i]]=d[p]+v[i];
 35                 fro[u[i]]=i;
 36                 sum[u[i]]=sum[p]+1;
 37             }
 38       }
 39     return;
 40 }
 41 int main()
 42 {
 43     scanf("%d",&n);
 44     for(int i=1;i<n;i++)
 45       {
 46         int a1,a2,a3;
 47         scanf("%d%d%d",&a1,&a2,&a3);
 48         jia(a1,a2,a3);
 49         jia(a2,a1,a3);
 50       }
 51     bfs(1);
 52     ll max1=0;
 53     for(int i=1;i<=n;i++)
 54       {
 55         if(max1<d[i])
 56           {
 57             max1=d[i];
 58             mx1=i;
 59           }
 60         f[i]=0;
 61       }
 62     bfs(mx1);
 63     max1=0;
 64     for(int i=1;i<=n;i++)
 65       {
 66         if(max1<d[i])
 67           {
 68             max1=d[i];
 69             ans=i;
 70           }
 71         f[i]=0;
 72       }
 73     ans1=d[ans];
 74     printf("%lld
",d[ans]/n);
 75     for(;ans;)
 76       {
 77         int p=fro[ans];
 78         v[p]--;
 79         v[p^1]--;
 80         ans=from[p];
 81       }
 82     bfs(1);
 83     max1=0;
 84     for(int i=1;i<=n;i++)
 85       {
 86         if(max1<d[i])
 87           {
 88             max1=d[i];
 89             mx1=i;
 90           }
 91         f[i]=0;
 92       }
 93     bfs(mx1);
 94     max1=0;
 95     for(int i=1;i<=n;i++)
 96       if(max1<d[i])
 97         {
 98             max1=d[i];
 99             ans=i;
100         }
101     printf("%lld
",ans1-d[ans]);
102     return 0;
103 }

先找一条直径,把直径上的边的权值减去1,再找一遍直径,差便是答案。

原文地址:https://www.cnblogs.com/xydddd/p/5309067.html