第十场 hdu 6178 (bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=6178

 

题目大意:

已知n个节点有n-1条连线,现在有k只猴子,每只猴子必须要住在一个节点上,两只猴子之间最少要有一条连线。问k只猴子最少要有多少条连线。

解题思路:

首先由于数据太大而且要在1s内完成所以应该用输入挂输入。测试了一下如果用scanf输入耗时995ms,如果用输入挂的话耗时421ms。
然后能够知道在一棵树中如果有成对的节点,可以知道节省的节点数最多就是成对的节点的个数。所以求出树的成对的节点个数是解决问题的关键。
最后找出度为1的节点放入队列中。使用bfs访问队列值now,然后找出它的子节点next,如果now和next都没有被访问过就把他们标记成访问,顺便把对数+1。然后在next的容器中删除now这个值,如果next容器的size是1,就把它放入队列中.

AC代码:

  1 #include <iostream>
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 namespace fastIO
  5 {
  6 #define BUF_SIZE 100000
  7 #define OUT_SIZE 100000
  8 #define ll long long
  9 //fread->read
 10 bool IOerror=0;
 11 inline char nc()
 12 {
 13     static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
 14     if (p1==pend)
 15     {
 16         p1=buf;
 17         pend=buf+fread(buf,1,BUF_SIZE,stdin);
 18         if (pend==p1)
 19         {
 20             IOerror=1;
 21             return -1;
 22         }
 23         //{printf("IO error!\n");system("pause");for (;;);exit(0);}
 24     }
 25     return *p1++;
 26 }
 27 inline bool blank(char ch)
 28 {
 29     return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
 30 }
 31 inline void read(int &x)
 32 {
 33     bool sign=0;
 34     char ch=nc();
 35     x=0;
 36     for (; blank(ch); ch=nc());
 37     if (IOerror)return;
 38     if (ch=='-')sign=1,ch=nc();
 39     for (; ch>='0'&&ch<='9'; ch=nc())x=x*10+ch-'0';
 40     if (sign)x=-x;
 41 }
 42 }
 43 using namespace fastIO;
 44 int degr[100005],vis[100005];
 45 vector<int>vec[100005];
 46 queue<int>que;
 47 int main()
 48 {
 49     int n,t,k,x;
 50     //freopen("1008.in","r",stdin);
 51     read(t);
 52     while(t--)
 53     {
 54         read(n);
 55         read(k);
 56         for(int i=0; i<=n; i++)
 57         {
 58             vec[i].clear();
 59             degr[i]=0;
 60             vis[i]=0;
 61         }
 62         for(int i=2; i<=n; i++)
 63         {
 64             read(x);
 65             vec[i].push_back(x);
 66             vec[x].push_back(i);
 67             degr[i]++;
 68             degr[x]++;
 69         }
 70         for(int i=1; i<=n; i++)
 71         {
 72             if(degr[i]==1)
 73             {
 74                 que.push(i);
 75             }
 76             degr[i]=0;
 77         }
 78         int ans=0;
 79         while(!que.empty())
 80         {
 81             int val=que.front();
 82             que.pop();
 83             int now=vec[val][0];
 84             if(vis[now]==0&&vis[val]==0)
 85             {
 86                 ans++;
 87                 vis[now]=1;
 88                 vis[val]=1;
 89             }
 90             vec[now].erase(remove(vec[now].begin(),vec[now].end(),val),vec[now].end());
 91             if(vec[now].size()==1)
 92                 que.push(now);
 93         }
 94         if(ans*2>k)
 95         {
 96             printf("%d\n",(k+1)/2);
 97         }
 98         else
 99         {
100             printf("%d\n",k-ans);
101         }
102     }
103     return 0;
104 }
View Code

 

posted @ 2017-08-25 16:11  Wally的博客  阅读(180)  评论(0编辑  收藏  举报