UVALive 6450 Social Advertising DFS解法

题意:一些人有朋友关系,在某个人的社交网站上投放广告可以被所有该人的直接朋友看到,问最小投放多少个广告使给出的人都看到广告。(n<=20)

解法:看到n的范围可以想到用二进制数表示每个人被覆盖与否,所以可以依次为状态进行搜索,每次枚举一个人,投放广告,然后将他的朋友覆盖,用dis记录步数,记忆化搜索。

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#define Mod 1000000007

using namespace std;

#define N 100007



int mp[22][22];

int mstep,n,S;

int tag;

int dis[1103300];



void dfs(int state,int step)

{

    int i;

    dis[state] = step;

    if(state == S)

    {

        mstep = min(mstep,step);

        return;

    }

    for(int i=0;i<n;i++)

    {

        //if((state&(1<<i)) == 0)  //不要,因为这个点可以是被覆盖的,还可以再放

        //{

            int tmp = state|(1<<i);

            for(int j=0;j<n;j++)

            {

                if(mp[i][j] && (tmp&(1<<j)) == 0)

                {

                    tmp|=(1<<j);

                }

            }

            if(!dis[tmp] || step+1 < dis[tmp])

            {

                dfs(tmp,step+1);

            }

        //}

    }

}



int main()

{

    int t,i,k,j,x;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d",&n);

        S = (1<<n)-1;

        memset(mp,0,sizeof(mp));

        memset(dis,0,sizeof(dis));

        for(i=0;i<n;i++)

        {

            scanf("%d",&k);

            for(j=0;j<k;j++)

            {

                scanf("%d",&x);

                mp[i][x-1] = 1;

                mp[x-1][i] = 1;

            }

        }

        mstep = Mod;

        dfs(0,0);

        printf("%d\n",mstep);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(Social)