zoukankan      html  css  js  c++  java
  • 「BalticOI 2015」网络

    题意简述:给你一颗(n)个点的树,问你至少需要加几条边,可以使得这棵树删去任意一条边后依然联通。并给出一种方案。

    很显然可以转化为对于树的任意一颗子树,都需要连一条边到其他子树,显然连叶子节点是最优的。

    考虑这样一种连边方案:设一共(k)个叶子节点,按(dfs)序排序,第(i)个叶子节点连向第(i+lceilfrac{k}{2} ceil)个叶子节点,容易证明这样连边一定不会存在一颗子树内没有边连向其他子树。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<set>
    using namespace std;
    #define rg register
    void read(int &x){
        char ch;bool ok;
        for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
        for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
    }
    const int maxn=5e5+10;
    int n,m,in[maxn],rt,dfn[maxn],id,k,w[maxn],nid[maxn];
    int pre[maxn*2],nxt[maxn*2],h[maxn],cnt;
    void ins(int x,int y){
        pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
        pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
    }
    void dfs(int x,int fa){
        dfn[x]=++id;nid[id]=x;
        for(rg int i=h[x];i;i=nxt[i])
    	if(pre[i]!=fa)dfs(pre[i],x);
        if(in[x]==1)w[++k]=dfn[x];
    }
    int main(){
        read(n);
        for(rg int i=1,x,y;i<n;i++)read(x),read(y),ins(x,y),in[x]++,in[y]++;
        for(rg int i=1;i<=n;i++)if(in[i]!=1){rt=i;break;}
        dfs(rt,0);printf("%d
    ",(k+1)/2);
        for(rg int i=1;i<=k/2;i++)printf("%d %d
    ",nid[w[i]],nid[w[i+(k+1)/2]]);
        if(k&1)printf("%d %d
    ",nid[w[k/2+1]],rt);
    }
    
  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/lcxer/p/11857707.html
Copyright © 2011-2022 走看看