HDU 5927 Auxiliary Set(DFS)

题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5927
题目大意:
(补题解中先把思路码上)

解题思路:
这里被memset坑了,注意到如果有10W个点,10W个询问,每次memset一次肯定爆炸。

先根据根节点建下树。
这里注意到不重要的点很少,我们从不重要点的遍历,如果不重要的点下面的两个子树中有两个重要的点,那么就将它变为重要的点,那么该如何节省memeset呢,我将非重要的点标记为了问题编号,对于第i个问题,非重要的点编号就是i。
对于一个编号为i的点。
如果遍历了这个点,且这个点能变成重要的点,那么把它编号变为0。
如果它不能变成重要的点,但是它下面有一个重要的点,那么它的编号为100005+i
如果它不能变成重要的点,它下面也没有重要的点,那么它的编号为为
-i。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <set>
#include <functional>
#define RI(N) scanf("%d",&(N))
#define RII(N,M) scanf("%d %d",&(N),&(M))
#define RIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
#define mem(a) memset((a),0,sizeof(a))
using namespace std;
const int inf=1e9;
const int inf1=-1*1e9;
double EPS=1e-10;
typedef long long LL;

vector<int> G[100005];
vector<int> real_G[100005];
vector<int> unimpotant;
int ans[100005],ans1=0;
int vis[100005],n,q;
int qqq;

void dfs(int x)
{
    for(int i=0; i<G[x].size(); i++)
    {
        int de=G[x][i];
        if(!vis[de])
        {
            vis[de]=1;
            real_G[x].push_back(de);
            dfs(de);
        }
    }
    return ;
}



void jianshu()
{
   for(int i=0; i<=n+1; i++)
        vis[i]=0;
    vis[1]=1;
    dfs(1);
}

int dfs1(int x)
{
    int summ=0;
    for(int i=0; i<real_G[x].size(); i++)
    {
        int d=real_G[x][i];
        if((ans[d]==qqq))  summ+=dfs1(d);
        else if(ans[d]!=-qqq)  summ++;
        if(summ>=2) break;
    }
    if(summ>=2)
    {
        ans[x]=0;
        return 1;
    }
    if(summ>=1)
    {
        ans[x]=100005+qqq;
        return 1;
    }
    ans[x]=-qqq;
    return 0;
}

void solve()
{
    for(int i=0; i<unimpotant.size(); i++)
    {
        int x=unimpotant[i];
        if(ans[x]==qqq) dfs1(x);
        if(ans[x]!=(-qqq)&&ans[x]!=100005+qqq) ans1++;
    }
    /*for(int i=1;i<=n;i++)
        if(ans[i]==0) cout<<"im = "<<i<<endl;*/
    printf("%d\n",ans1);
}

int main()
{
    int T,cas=1;
    RI(T);
    while(T--)
    {
        printf("Case #%d:\n",cas++);
        RII(n,q);
        for(int i=0; i<=n+1; i++)
        {
            G[i].clear();
            real_G[i].clear();
        }
        for(int i=1; i<=n-1; i++)
        {
            int x,y;
            RII(x,y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        jianshu();

        memset(ans,0,sizeof(int)*(n+2));
        for(int i=1; i<=q; i++)
        {
            qqq=i;
            ans1=0;
            int m,x;
            RI(m);
            ans1+=n-m;
            unimpotant.clear();
            for(int j=0; j<m; j++)
            {
                RI(x);
                unimpotant.push_back(x);
                ans[x]=qqq;
            }
            solve();
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/q610376681/article/details/52778173