题目描述
拜特朗政府已经决定,现在是时候将他们的小国家与互联网连接起来,以便所有公民都能参加节目比赛,观看可爱猫的视频。当是时候建设这个国家的网络骨干时,他们给互联网乐观主义者公司分配了连接所有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 ",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 ",ans[i],ans[i+tot/2]); 22 } 23 if (tot&1) printf("%d %d ",ans[tot/2],ans[tot]); 24 }