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

 

转载于:https://www.cnblogs.com/whatbeg/p/3886931.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值