zoukankan      html  css  js  c++  java
  • bzoj1912(树的直径)

    BZOJ1912」[Apio2010] patrol 巡逻

    Description

    Input

    第一行包含两个整数 n, K(1 ≤ K ≤ 2)。接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n)。

    Output

    输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离。

    Sample Input

    8 1
    1 2
    3 1
    3 4
    5 3
    7 5
    8 5
    5 6

    Sample Output

    11

    HINT

    10%的数据中,n ≤ 1000, K = 1;
    30%的数据中,K = 1;
    80%的数据中,每个村庄相邻的村庄数不超过 25;
    90%的数据中,每个村庄相邻的村庄数不超过 150;
    100%的数据中,3 ≤ n ≤ 100,000, 1 ≤ K ≤ 2。

    k=1直接求树的直径

    k=2时把原来直径权值变为负值求直径,因为形成的两个环可能有重叠,取反后-(-1)变为+1

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int maxn=100000+10;
    const int nil=0x3f3f3f3f;
    
    struct my{
        int v;
        int next;
        int w;
    };
    
    my bian[maxn*2];
    queue<int>Q;
    int ans;
    int p,fa=1,adj[maxn],d[maxn],pre[maxn],dp[maxn],vis[maxn],n,k;;
    
    void myinsert(int u,int v,int w){
         bian[++fa].v=v;
         bian[fa].w=w;
         bian[fa].next=adj[u];
         adj[u]=fa;
    }
    
    int bfs(int s){
        memset(d,0x3f,sizeof(d));
        Q.push(s);
        d[s]=0;
        pre[s]=0;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            for (int i=adj[u];i;i=bian[i].next){
                int v=bian[i].v;
                if(d[v]==nil) {
                    d[v]=d[u]+1;
                    pre[v]=i;
                    Q.push(v);
                }
            }
        }
        int x,y;
        for (x=y=1;x<=n;x++) if(d[x]>d[y]) y=x;
        return y;
    }
    
    int get(){
        p=bfs(1);
        p=bfs(p);
        return d[p];
    }
    
    int dfs(int x){
         vis[x]=true;
         for (int i=adj[x];i;i=bian[i].next){
            int v=bian[i].v;
            if(!vis[v]){
                dfs(v);
                ans=max(ans,dp[x]+dp[v]+bian[i].w);
                dp[x]=max(dp[x],dp[v]+bian[i].w);
            }
         }
         return ans;
    }
    
    void change(){
         for (;pre[p];p=bian[pre[p]^1].v) {//可以记录路径,但是一直没搞懂是怎么回事,可能是我太弱吧,记住好了
               // printf("%d %d ",bian[pre[p]].v,bian[pre[p]^1].v);
                bian[pre[p]].w=bian[pre[p]^1].w=-1;
         }
    }
    
    int main(){
        int u,v;
        scanf("%d%d",&n,&k);
        for (int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            myinsert(u,v,1);
            myinsert(v,u,1);
        }
        int x=get();
        if(k==1){
            printf("%d
    ",2*(n-1)-(x-1));
        }
        else {
            change();
            int y=dfs(1);
            printf("%d
    ",2*n-x-y);
        }
    return 0;
    }
  • 相关阅读:
    java控制台输入
    冒泡排序
    选择排序
    Json数组去重
    HTTP状态码详解
    根据json对象的值替换json数组里的值
    用户中心页面
    正则表达式
    vue-router如何根据不同的用户给不同的权限
    vue2.0+element+node+webpack搭建的一个简单的后台管理界面
  • 原文地址:https://www.cnblogs.com/lmjer/p/9355780.html
Copyright © 2011-2022 走看看