Fork me on GitHub

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

 

posted @ 2014-08-02 14:00  whatbeg  阅读(184)  评论(0编辑  收藏  举报