ACM Battle(巧妙暴力)

来源:互联网 发布:windows hadoop2.6 编辑:程序博客网 时间:2024/06/05 20:40
古往今来的各种传说中存在着很多魔法阵,它们的激活方式也各不相同。传说在北师大电子楼前的小花园里就有一个魔法阵,上次出现还是在很多很多很多年前,但是现在它又出现了!
这时,小Q同学面无表情地说:“传说这个魔法阵都会在都会在来自远古的恶魔Awesome Crystal Monster(ACM)降临的时候出现,现在,这个时候终于要到来了吗!”话音未落,小Q同学已经走到了魔法阵前,取出一个小瓶,开始用瓶中的圣水激活这个魔法阵,“你们快退后,这里就交给我了!”

这个魔法阵由一些点和一些连接这些点的边构成,当小Q同学把圣水滴在一个点上时,和这个点相连的所有边就会被点亮并发出神圣的光芒,当魔法阵所有的边都点亮的时候,就会出现强大的神圣力量。但是小Q同学拥有的圣水非常有限,只有10滴,现在小Q同学想知道他最少可以用多少滴圣水点亮整个魔法阵,如果耗尽圣水也不能点亮,就只能打出一波GG了。

输入描述:

第一行包含一个正整数T(≤ 20),表示测试数据的组数,对于每组测试数据,第一行是两个整数n(1 ≤ n ≤ 1000)和m(1 ≤ m ≤ 2000),表示魔法阵的点数和边数,接下来m行,每行包含两个整数u,v(1 ≤ u,v ≤ n),表示有一条边连接了u号点和v号点。

输出描述:

对于每组测试数据,如果使用不超过10滴圣水可以点亮整个魔法阵,输出最少需要的圣水滴数,否则输出"GG"(不含引号)。
示例1

输入

24 31 21 31 44 41 22 33 44 1

输出

12

说明

对于第一组样例,最优方案是在1号点滴一滴圣水,对于第二组样例,一个最优方案是在1号点和3号点各滴一滴圣水。

题目思路:

一开始写了一个毫无证明的贪心,顺了wa了,我们从数据来看只有10,所以应该跟暴力有关系,但是怎么去暴力呢,对于这个来说

我们容易想到去枚举点的子集,但是n有1000,那么复杂度有2^1000*m ,显然不行,我们分析可以发现,对于每一条边,他的两个顶点一定是有至少一个被染色了的,所以我们可以去考虑每一条边,对于当前边如果有至少一个顶点被染色,那么就去继续遍历,否则就去回溯哪一个顶点被染色了,如果深度超过10直接就退出,复杂度是2^10*m

这题的关键点就是发现对于一条边来说,肯定要有一个顶点被染色,这样我们就能继而想到枚举边,根据边的情况分析。

ac代码:

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<sstream>#include<map>#include<vector>#include<set>#define LL long long#define INF 0x3f3f3f3f#define LLINF 0x3f3f3f3f3f3f3f#define lson rt<<1#define rson rt<<1|1using namespace std;int T;int n,m;struct node{    int u,v;}E[2000+5];int vis[1000+5];int ans = INF;void dfs(int sum,int deep){    if(deep>10){        return;    }    if(sum==m){        ans = min(deep,ans);        return ;    }    if(vis[E[sum].u]||vis[E[sum].v]){        dfs(sum+1,deep);    }    else{        vis[E[sum].u] = 1;        dfs(sum+1,deep+1);        vis[E[sum].u] = 0;        vis[E[sum].v] = 1;        dfs(sum+1,deep+1);        vis[E[sum].v] = 0;    }}int main(){    scanf("%d",&T);    while(T--){        ans = INF;        scanf("%d%d",&n,&m);        memset(vis,0,sizeof(vis));        for(int i = 0;i<m;i++){            int a,b;            scanf("%d%d",&E[i].u,&E[i].v);        }        dfs(1,0);        if(ans<=10)        cout<<ans<<endl;        else{            puts("GG");        }    }}


阅读全文
0 0
原创粉丝点击