JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
企鵝國的網吧們之間由網線互相連接,形成一棵樹的結構?,F在由于冬天到了,供暖部門缺少燃料,于是他們決定去拆一些網線來做燃料。但是現在有K只企鵝要上網和別人聯機游戲,所以他們需要把這K只企鵝安排到不同的機房(兩只企鵝在同一個機房會吵架),然后拆掉一些網線,但是需要保證每只企鵝至少還能通過留下來的網線和至少另一只企鵝聯機游戲。
所以他們想知道,最少需要保留多少根網線?
Input
第一行一個整數T,表示數據組數;
每組數據第一行兩個整數N,K,表示總共的機房數目和企鵝數目。
第二行N-1個整數,第i個整數Ai表示機房i+1和機房Ai有一根網線連接(1≤Ai≤i)。
Output
每組數據輸出一個整數表示最少保留的網線數目。
Sample Input
2
4 4
1 2 3
4 3
1 1 1
Sample Output
2
2
Data Constraint
對于30%的數據:N≤15;
對于50%的數據:N≤300;
對于70%的數據:N≤2000;
對于100%的數據:2≤K≤N≤100000,T≤10。
Solution
一眼貪心。
顯然最優的情況一定是一條邊匹配兩個點,如果能這樣匹配就直接直接輸出了。
但是有可能樹的形狀不能滿足這樣的匹配,于是剩下的點就只能用一條一條的邊匹配了。
處理匹配的話就從下往上貪心地匹配即可。
時間復雜度 O(T?N) 。
Code
#include<cstdio> #include<cstring> using namespace std; const int N=1e5+1; int tot,ans; int first[N],next[N],en[N]; bool bz[N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline void insert(int x,int y) {next[++tot]=first[x];first[x]=tot;en[tot]=y; } inline void dfs(int x,int y) {for(int i=first[x];i;i=next[i])if(en[i]!=y){dfs(en[i],x);if(!bz[x] && !bz[en[i]]) bz[x]=true,ans++;} } int main() {int T=read();while(T--){int n=read(),k=read();memset(first,tot=ans=0,sizeof(first));memset(bz,false,sizeof(bz));for(int i=2;i<=n;i++) insert(read(),i);dfs(1,0);if(ans<<1>=k) printf("%d\n",(k>>1)+(k&1)); elseprintf("%d\n",ans+(k-ans*2));}return 0; }總結
以上是生活随笔為你收集整理的JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5453. 【NOIP2017
- 下一篇: JZOJ 5456. 【NOIP2017