[dfs] Luogu P4665 Network

题目描述

拜特朗政府已经决定,现在是时候将他们的小国家与互联网连接起来,以便所有公民都能参加节目比赛,观看可爱猫的视频。当是时候建设这个国家的网络骨干时,他们给互联网乐观主义者公司分配了连接所有N个拜特兰德的电脑。这些连接是作为计算机对之间的直接连接,使任何一对计算机都通过一系列的链接连接起来。

拜特朗是一个发展中国家,因此,为了将成本降到最低,网络拓扑是以树的形式构建的(即有N−1个计算机之间的直接连接)。为时已晚,人们意识到这一解决方案存在严重缺陷。如果只有一个链接断了,那么拜特兰德的计算机就会被分割,这样一些计算机就不能互相通信了!为了提高拜特朗网络的可靠性,人们决定至少要容忍单个链路中断。你的任务是帮助互联网乐观主义者公司以最便宜的方式改进网络。给出了拜特朗的网络拓扑(即N−1个计算机对是通过直接链接连接的),找到需要添加的最少数量的链接,以便如果任何单个链接中断,网络仍将被连接。

 

题解

  • 找到所有叶子节点,也就是度为1的点,把它们连起来就行了,因为要保证相邻的连上,跑一遍dfs

代码

 1 #include <iostream>
 2 #include <cstdio>
 3 #define N 500010
 4 using namespace std;
 5 int n,tot,cnt,head[N],ans[N],du[N];
 6 struct edge { int to,from; }e[N*2];
 7 void insert(int x,int y) { e[++cnt].to=y,e[cnt].from=head[x],head[x]=cnt; }
 8 void dfs(int x,int fa)
 9 {
10     if (du[x]==1) ans[++tot]=x;
11     for (int i=head[x];i;i=e[i].from) if (e[i].to!=fa) dfs(e[i].to,x);
12 }
13 int main()
14 {
15     scanf("%d",&n);
16     for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(x,y),insert(y,x),du[x]++,du[y]++;
17     dfs(1,0),printf("%d\n",tot-tot/2);
18     for (int i=1;i<=tot/2;i++)
19     {
20         if (ans[i]>=ans[i+tot/2]) swap(ans[i],ans[i+tot/2]);
21         printf("%d %d\n",ans[i],ans[i+tot/2]);
22     }
23     if (tot&1) printf("%d %d\n",ans[tot/2],ans[tot]);
24 }

 

posted @ 2019-07-23 14:11  BEYang_Z  阅读(137)  评论(0编辑  收藏  举报