标签:企鹅 Contest1351 Ai 整数 机房 网线 数据
题面
Description
【问题描述】
企鹅国的网吧们之间由网线互相连接,形成一棵树的结构。现在由于冬天到了,供暖部门缺少燃料,于是他们决定去拆一些网线来做燃料。但是现在有K只企鹅要上网和别人联机游戏,所以他们需要把这K只企鹅安排到不同的机房(两只企鹅在同一个机房会吵架),然后拆掉一些网线,但是需要保证每只企鹅至少还能通过留下来的网线和至少另一只企鹅联机游戏。
所以他们想知道,最少需要保留多少根网线?
【输入格式】
第一行一个整数T,表示数据组数;
每组数据第一行两个整数N,K,表示总共的机房数目和企鹅数目。
第二行N-1个整数,第i个整数Ai表示机房i+1和机房Ai有一根网线连接(1≤Ai≤i)。
【输出格式】
每组数据输出一个整数表示最少保留的网线数目。
【输入样例】
2
4 4
1 2 3
4 3
1 1 1
【输出样例】
2
2
【数据范围】
对于30%的数据:N≤15;
对于50%的数据:N≤300;
对于70%的数据:N≤2000;
对于100%的数据:2≤K≤N≤100000,T≤10。
题意
有一颗树,要求删最多的边,但要使得每个点必须至少与一个点相连。问最少剩几条边。
题解
按拓扑序贪心,正确性我也不会证
#include<iostream> #include<cstring> using namespace std; const int N=2e5+5; struct edge{ int v,next; }e[N<<1]; int t,n,k,head[N],cnt,clo,rk[N],ans; bool vis[N]; void add(int u,int v){ e[++cnt]=(edge){v,head[u]}; head[u]=cnt; } void dfs(int u,int fa){ for(int i=head[u];i;i=e[i].next){ int v=e[i].v; if(v==fa)continue; dfs(v,u); } rk[++clo]=u; } int main(){ scanf("%d",&t); while(t--){ ans=cnt=clo=0; memset(vis,0,sizeof(vis)); memset(head,0,sizeof(head)); scanf("%d%d",&n,&k); for(int i=1;i<n;i++){ int x; scanf("%d",&x); add(i+1,x); add(x,i+1); } dfs(1,0); for(int i=1;i<=n;i++){ if(k<=1)break; int u=rk[i]; if(vis[u])continue; for(int j=head[u];j;j=e[j].next){ int v=e[j].v; if(!vis[v]){ vis[v]=1; ans++; k-=2; break; } } vis[u]=1; } ans+=k; printf("%d\n",ans); } }
标签:企鹅,Contest1351,Ai,整数,机房,网线,数据 来源: https://www.cnblogs.com/Evan704/p/11412487.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。