zoukankan      html  css  js  c++  java
  • LA 6450 Social Advertising

    【题目】

    给一个无向图,每当对某个点操作,该点以及与该点相连的点都获得标记,问标记所有点至少需要操作多少次

    输入

    第一行为T,表示测试数据组数

    每组测试数据第一行为n(1<=n<=20)表示有n个点,接下来n行,第i行描述与结点i所连的点,首个整数d,接下来有d个整数,表示结点i与它之间有一条边,该图没有自环

    输出

    每组测试数据输出一行,一个数表示至少需要操作的次数

    【题解】

    状态压缩+枚举

    这道题数据范围好小,那么就应该不是什么特殊的算法了,可以考虑下搜索

    将每个点与其他点的关系压缩,记录到数组中(比如a[i]),用一个最长20位的二进制数记录,比如结点i,当他的第j位是1,表示ij之间有一条边,我们不妨设结点i的第i位为1

    我们设b代表当前每个点是否被标记的状态,第i位为1表示结点i已经被标记,初始时b0,就是什么点都没有被标记。

    那么开始搜索,不断枚举点,比如说枚举第i个结点,则调出来他与其他点的连接关系a[i],则b=b|a[i],一直枚举知道b=1<<n-1即可1<<n-1就是所有点都被标记的状态

    但是DFS会超时,我们改变思路,只需枚举每个点是否被标记就可以了,枚举从11<<n-1,比如说枚举到i,其第j位为1表示我们对结点j操作,每枚举一个数,就统计一下它的二进制中有多少个1,统计满足条件时1的最小个数就可以了~

    【吐槽】

    竟然不是DP,竟然不是DP,还好不是,状压DP用着还不熟练。

    一开始真的用DFS,但是TLE,接着加了各种剪枝,还是TLE,最后死心想想还是枚举一下标记状态吧,结果竟然AC了,比DFS加上剪枝还要快!还是位运算大法好啊。

    【代码】

    RunID

    User

    Problem

    Result

    Memory

    Time

    Language

    Length

    Submit Time

    2549596

    zhyfzy

    G

    Accepted

    0 KB

    1516 ms

    C++ 4.5.3

    939 B

    2014-07-31 16:15:30

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #define eps 0.000001
    #define N 30000
    #define M 60000
    using namespace std;
    int i,j,k,n,m,x,y,T,b,a[300],tar,ans,tt;
    	
    int main()
    {
    	scanf("%d",&T);
    	while (T--)
    	{
    		memset(a,0,sizeof(a));
    		scanf("%d",&n);
    		tar=(1<<n)-1;
    		for (i=1;i<=n;i++)
    		{
    			scanf("%d",&k);
    			a[i]=a[i]|1<<(i-1);
    			for (j=1;j<=k;j++)
    			{
    				scanf("%d",&x);
    				a[i]=a[i]|1<<(x-1);
    			}
    		}
    		ans=300;b=0;
    		for (i=1;i<=tar;i++)
    		{
    			b=i;tt=0;
    			for (j=1;j<=n;j++)
    				if ((b&(1<<(j-1))))
    				{
    					tt++;
    				}
    			for (j=1;j<=n;j++)
    			{
    				if ((i&(1<<(j-1))))
    				{
    					b=b|a[j];
    					if (b==tar) break;
    				}
    			}
    			if (b==tar) ans=min(ans,tt);
    		}
    		printf("%d
    ",ans);
    	}
    }


  • 相关阅读:
    【转载】C#使用Split函数根据特定分隔符分割字符串
    【转载】 Asp.Net安全之防止脚本入
    【转载】C#使用as关键字将对象转换为指定类型
    【转载】C#使用is关键字检查对象是否与给定类型兼容
    【转载】C#将字符串中字母全部转换为大写或者小写
    【转载】使用Response.WriteFile输出文件以及图片
    【转载】常见面试题:C#中String和string的区别分析
    【转载】Asp.Net中Cookie对象的作用以及常见属性
    【转载】C#指定文件夹下面的所有内容复制到目标文件夹下面
    【转载】Asp.Net中应用程序的事件响应次序
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4021317.html
Copyright © 2011-2022 走看看