upc 9328 开会

9328: 开会

时间限制: 1 Sec  内存限制: 128 MB
提交: 127  解决: 24
[提交] [状态] [讨论版] [命题人:admin]

题目描述

开会,是对所有人时间的浪费,是对集体的谋杀。
山区学校的一些学生之间的关系似乎好得有点过头,以至于传出了一些(在风纪委员们看来)不好的绯闻。具体地,有n个学生,n-1条绯闻,每条绯闻的主角都是俩学生。记者们的恶趣味保证任意两个学生,可以通过若干条绯闻直接或间接地联系在一起。
于是学校打算邀请一些学生参加座谈会。
校长相信,假如邀请了某位学生x来开会,那么就能够震慑到x本人,以及和x在同一条绯闻里的学生们。
矿泉水是宝贵的,校长想知道最少需要请多少人来开会,才有可能震慑到所有同学。

 

输入

第一行是 n 表示学生数。 
之后n-1行,每行俩整数x,y,表示学生x和y之间有绯闻。( x≠y,但不一定x<y )

 

输出

一行,一个整数表示最少要邀请多少人。 

 

样例输入

5
1 3
5 2
4 3
3 5

 

样例输出

2

 

提示

可以选择邀请学生2&3,或者是邀请学生3&5 

对于前10%的数据,n<=15
对于前30%的数据,n<=2000
对于接下来30%的数据,n<=10^5,且有俩学生需要通过n-1条绯闻才能扯上关系。
对于前100%的数据,n<=10^5,1<=x,y<=n

 

题意:

  不好解释,不解释了。

分析

  求最小支支配集就可以了。

  

///  author:Kissheart  ///
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
int head[MAX*2],cur,a[MAX];
int vis[MAX],n,pre[MAX],num;

struct node
{
    int u,next;
}e[MAX*2];
void add(int u,int v)
{
    e[++cur].u=v;
    e[cur].next=head[u];
    head[u]=cur;
}

void dfs(int u)
{
    a[++num]=u;
    for(int i=head[u];i;i=e[i].next)
    {
        if(vis[e[i].u]) continue;

        vis[e[i].u]=1;
        pre[e[i].u]=u;
        dfs(e[i].u);
    }
}
int s[MAX];
int MDS()
{
    int ans=0,p;
    memset(vis,0,sizeof(vis));

    for(int i=num;i>=1;i--)
    {
        p=a[i];
        if(!vis[p])
        {
            if(!s[pre[p]])
            {
                s[pre[p]]=1;
                ans++;
            }

            vis[p]=1;
            vis[pre[p]]=1;
            vis[pre[pre[p]]]=1;
        }
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n-1;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }

    vis[1]=1;
    pre[1]=1;
    dfs(1);
   /* for(int i=1;i<=num;i++)
        printf("%d ",a[i]);*/

    printf("%d\n",MDS());
    return 0;
}
View Code

 

posted @ 2018-11-10 16:53  Kissheart_LMC  阅读(191)  评论(0编辑  收藏  举报