zoukankan      html  css  js  c++  java
  • BZOJ3124 SDOI2013直径

      本以为必有高论,结果是个思博题。随便找一条直径,最后答案肯定是这条直径上的连续一段,如果某分支长度等于直径上某端的长度这一端都要被剪掉。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 200010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,p[N],fa[N],son[N],t,cnt,root,x;
    ll deep[N],ans;
    struct data{int to,nxt,len;
    }edge[N<<1];
    void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
    void dfs(int k,int from)
    {
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=from)
        {
            deep[edge[i].to]=deep[k]+edge[i].len;
            fa[edge[i].to]=k;
            dfs(edge[i].to,k);
        }
    }
    ll findmax(int k)
    {
        ll mx=deep[k];
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=fa[k]) mx=max(mx,findmax(edge[i].to));
        return mx;
    }
    void solve(int k)
    {
        ll mx=0;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=fa[k]&&edge[i].to!=son[k]) mx=max(mx,findmax(edge[i].to));
        if ((deep[k]<<1)==mx&&mx) cnt=0;
        if (mx==ans) {cout<<cnt<<endl;exit(0);}
        if (son[k]) cnt++,solve(son[k]);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3124.in","r",stdin);
        freopen("bzoj3124.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<n;i++)
        {
            int x=read(),y=read(),z=read();
            addedge(x,y,z),addedge(y,x,z);
        }
        deep[1]=0;dfs(1,1);
        root=1;for (int i=2;i<=n;i++) if (deep[i]>deep[root]) root=i;
        deep[root]=0;fa[root]=0;dfs(root,root);
        x=1;for (int i=2;i<=n;i++) if (deep[i]>deep[x]) x=i;
        ans=deep[x];cout<<ans<<endl;
        while (fa[x]) son[fa[x]]=x,x=fa[x];
        solve(root);
        return 0;
    }
  • 相关阅读:
    TCP/IP讲解
    Android开发的技术层次
    页面右下角弹出类似QQ或MSN的消息提示
    C# winform 自定义鼠标图标
    C#遍历指定文件夹中的所有文件
    C#操作Word
    关于数据绑定的一些小技巧
    Silverlight遍历本地文件夹
    ckeditor+ckfinder+syntaxhighlight实现上传和插入代码高亮(for .NET)
    wpf 动画效果
  • 原文地址:https://www.cnblogs.com/Gloid/p/10014361.html
Copyright © 2011-2022 走看看