zoukankan      html  css  js  c++  java
  • [Sdoi2013]直径(树的直径)

    //36分

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<algorithm>
    #include<map>
    using namespace std;
    typedef long long ll;
    
    #define setfire(name) freopen(#name".in","r",stdin);freopen(#name".out","w",stdout);
    #define fre(name) freopen(#name".txt","r",stdin);
    #ifdef WIN32
    #define LL "%lld"
    #else
    #define LL "%I64d"
    #endif
    
    const int N=2e5+5;
    const int Z=2005;
    int n,S1,S2,la,lb,s_cnt,b[N],stack[N],prev[N];char s[50];bool vis[N];
    struct edge{int u,v,next;ll w;}e[N<<1];int tot=1,head[N];
    int dep[N],fa[N][19];
    ll ans,LEN,dis[N],dist[N];
    bool mark[Z][Z];
    struct data{int x,y;}state[N];
    inline int read(){
        int x=0;char ch=getchar();
        while(ch<'0'||ch>'9'){ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x;
    }
    inline void add(int x,int y,int z){
        e[++tot].u=x;e[tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
        e[++tot].u=y;e[tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
    }
    void BFS(int S){
        int top=1;
        stack[top]=S;dep[S]=1;fa[S][0]=S;
        while(top){
            int x=stack[top--];
            for(int i=head[x];i;i=e[i].next){
                if(e[i].v!=fa[x][0]){
                    fa[e[i].v][0]=x;
                    dep[e[i].v]=dep[x]+1;
                    dist[e[i].v]=dist[x]+e[i].w;
                    stack[++top]=e[i].v;
                }
            }
        }
    }
    inline int bfs(int S){
        memset(dis,-1,sizeof dis);
        memset(vis,0,sizeof vis);
        int id=0,mx=-1,top=1;
        stack[top]=S;dis[S]=0;vis[S]=1;
        while(top){
            int x=stack[top--];
            for(int i=head[x];i;i=e[i].next){
                if(!vis[e[i].v]&&dis[e[i].v]<dis[x]+e[i].w){
                    vis[e[i].v]=1;
                    dis[e[i].v]=dis[x]+e[i].w;
                    if(dis[e[i].v]>mx) mx=dis[e[i].v],id=e[i].v;
                    stack[++top]=e[i].v;
                }
            }
        }
        return id;
    }
    void gosolve(int S,int T){
        memset(vis,0,sizeof vis);
        int id=0,mx=-1,top=1;
        stack[top]=S;vis[S]=1;
        while(top){
            int x=stack[top--];
            for(int i=head[x];i;i=e[i].next){
                if(!vis[e[i].v]){
                    vis[e[i].v]=1;
                    prev[e[i].v]=i;
                    if(e[i].v==T){top=0;break;} 
                    stack[++top]=e[i].v;
                }
            }
        }
        for(int i=T;i!=S;i=e[prev[i]^1].v)  b[prev[i]>>1]++;
    } 
    int lca(int a,int b){
        if(dep[a]<dep[b]) swap(a,b);
        int t=dep[a]-dep[b];
        for(int i=0;i<=18;i++){
            if(t&(1<<i)){
                a=fa[a][i];
            }
        }
        if(a==b) return a;
        for(int i=18;i>=0;i--){
            if(fa[a][i]!=fa[b][i]){
                a=fa[a][i];
                b=fa[b][i];
            }
        }
        return fa[a][0];
    }
    void init(){
        n=read();
        for(int i=1,x,y,z;i<n;i++) x=read(),y=read(),z=read(),add(x,y,z);
    }
    void dp_tree_len(int x,int fa){
        for(int i=head[x],y;i;i=e[i].next){
            if((y=e[i].v)!=fa){
                if((x==la&&y==lb)||(x==lb&&y==la)) continue;
                dp_tree_len(y,x);
                LEN=max(LEN,dis[x]+dis[y]+e[i].w);
                dis[x]=max(dis[x],dis[y]+e[i].w);
            }
        }
    }
    void work(){
        if(n<=100){
            BFS(1);
            for(int i=1,mx=0;i<=n;i++) if(dist[i]>mx) mx=dist[i],S1=i;
            S2=bfs(S1);
            LEN=dis[S2];
            printf("%I64d
    ",LEN);
            for(int j=1;j<=18;j++){
                for(int i=1;i<=n;i++){
                    fa[i][j]=fa[fa[i][j-1]][j-1];
                }
            }
            ll lt;
            for(int i=1,anc;i<=n;i++){
                for(int j=1;j<i;j++){
                    if(mark[i][j]) continue;
                    anc=lca(i,j);
                    lt=dist[i]+dist[j]-dist[anc]*2;
                    if(lt==LEN) mark[i][j]=1,state[++s_cnt]=(data){i,j};
                }
            }    
            //直径条数 
            for(int i=1;i<=s_cnt;i++){
                gosolve(state[i].x,state[i].y);
            }
            int num=0;
            for(int i=1;i<=n;i++) if(b[i]==s_cnt) num++;
            printf("%d",num);
        }
        else{
            dp_tree_len(1,1);
            printf("%I64d
    ",LEN);
        }
    }
    int main(){
        freopen("diameter.in","r",stdin);
        freopen("diameter.out","w",stdout);
        int size=64<<20;
        char *p=(char*)malloc(size)+size;
        __asm__("movl %0,%%esp
    "::"r"(p));
        init();
        work();
        return 0;
    } 
  • 相关阅读:
    Ubuntu 16.04 LTS nodejs+pm2+nginx+git 基础安装及配置环境(未完,未整理)
    JavaScript 二、eval 和 with 函数
    JavaScript 一、 ES6 声明变量,作用域理解
    UNMET PEER DEPENDENCY @angular/common@2.3.1
    Laravel Homestead 离线安装
    mac os x 记录 转载
    Ubuntu 16.04 LTS 完善解决亮度调整
    oh my zsh 切换 bash
    关于bitmap储存图片报内存不足的问题
    .net操作sqlserver数据库
  • 原文地址:https://www.cnblogs.com/shenben/p/6431347.html
Copyright © 2011-2022 走看看