zoukankan      html  css  js  c++  java
  • BZOJ 3124 SDOI2013 直径

    首先直径是很好求的,先以任意点为根DFS求出最远点,再以最远点为根求出第二个点

    两个点之间的距离即为直径

    显然对于第二问,答案是直径上的某一段,且满足不可向左右扩展出跟直径等长的路径

    那么我们就可以暴力枚举直径上的点,看看它是否可以向右和向左扩展即可

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
     
    typedef long long LL;
    const int maxn=200010;
    int n,u,v,w;
    int A,B,L,ans;
    int h[maxn],cnt=1;
    struct edge{
        int to,next,w;
    }G[maxn<<1];
    LL dis[maxn],now,tmp,D;
    int fa[maxn];
    bool vis[maxn];
    void add(int x,int y,int z){++cnt;G[cnt].to=y;G[cnt].next=h[x];G[cnt].w=z;h[x]=cnt;}
    void read(int &num){
        num=0;char ch=getchar();
        while(ch<'!')ch=getchar();
        while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
    }
    void DFS(int u,int f,int &c){
        if(dis[u]>now)now=dis[u],c=u;
        for(int i=h[u];i;i=G[i].next){
            int v=G[i].to;
            if(v==f)continue;
            dis[v]=dis[u]+G[i].w;
            fa[v]=i;
            DFS(v,u,c);
        }return;
    }
    void Get_Len(){
        now=-1;dis[1]=0;fa[1]=0;DFS(1,-1,A);
        now=-1;dis[A]=0;fa[A]=0;DFS(A,-1,B);
        printf("%lld
    ",dis[B]);D=dis[B];
    }
    void check(int u,int f){
        if(dis[u]>tmp)tmp=dis[u];
        for(int i=h[u];i;i=G[i].next){
            int v=G[i].to;
            if(v==f)continue;
            if(vis[v])continue;
            dis[v]=dis[u]+G[i].w;
            check(v,u);
        }return;
    }
    void Get_ans(){
        now=0;
        for(int i=B;i;i=G[fa[i]^1].to)vis[i]=true;
        for(int i=fa[B];i;i=fa[G[i^1].to]){
            ans++;now+=G[i].w;
            tmp=-1;dis[G[i^1].to]=0;
            check(G[i^1].to,-1);
            if(tmp==now)L=ans;
            if(tmp==D-now)break;
        }printf("%d
    ",ans-L);
    }
     
    int main(){
        read(n);
        for(int i=1;i<n;++i){
            read(u);read(v);read(w);
            add(u,v,w);add(v,u,w);
        }
        Get_Len();Get_ans();
        return 0;
    }
    

      

  • 相关阅读:
    Linux下使用wireshark权限问题
    Ubuntu关机出错卡死 PCIe Bus Error: severity=Corrected, type=Physical Layer, id=00e5(Receiver ID)
    东南大学《操作系统》课程作业 第二章
    东南大学《操作系统》课程作业 第一章
    东南大学《操作系统》课程作业 第三章
    回溯算法
    拓扑排序之课程表问题
    C++虚函数多态
    JMETER安装及基本使用
    JMETER正则表达式提取器使用
  • 原文地址:https://www.cnblogs.com/joyouth/p/5392757.html
Copyright © 2011-2022 走看看