POJ 1482 It's not a Bug, It's a Feature! 状压+spfa

http://poj.org/problem?id=1482

题意:先黑了一发程序猿,说软件总是有漏洞,然后打补丁拆了东墙补西墙。现在软件有不超过20个漏洞,有不超过100个补丁,每个补丁有运用条件(某些漏洞不能存在,某些漏洞必须存在)和作用效果(补漏洞,产生新漏洞),已经安装时间,开始有所有漏洞,问是否有一种安装补丁的顺序能填补所有漏洞,并求最短的时间。

分析:因为只有20个漏洞,所以可以状压,大概100万的级别,每位为0表示没有这个漏洞,为1表示有这个漏洞。记f[i]表示达到状态i所需最短时间,初始状态即 f[(1<<n)-1] = 0,目标状态为f[0]。

开始用dfs把序列里的0全部枚举成+-,然后连边spfa。。最后要么mle,要么wa,要么re。。直接连边,边数太大了。。实际上很多状态和边是没有必要的。具体怎么转移还是看程序吧。。

注意位运算优先级十分低,连比较运算符都低,所以尽量多加括号。

记忆化搜索貌似写不好会爆栈,然后网上还有的用bfs+堆过的。。仔细观察了一下貌似是spfa的“堆优化”,估计和上次slf优化一样,会被某些数据卡。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 const int maxq = (1<<20) + 10;
 7 int q[(1<<20)+15];
 8 int n, m, maxn, oo, w[110];
 9 int f[(1<<20)+10], ha[(1<<20)+10];
10 int cas = 0;
11 char s1[30], s2[30];
12 bool in[(1<<20)+10];
13 int pre[110][2], fixed[110][2];
14 void cook_the_raw(int i)
15 {
16     pre[i][0] = pre[i][1] = fixed[i][1] = 0;
17     fixed[i][0] = maxn;
18     for (int j = 0; j < n; j++){
19         if (s1[j] == ‘+‘) pre[i][1] += 1 << j;        //pre[i][1]某位为1表示patch[i]apply条件要求该漏洞
20         else if (s1[j] == ‘-‘) pre[i][0] += 1 << j;     //pre[i][0]某位为1表示patch[i]apply条件要求无该漏洞
21         if (s2[j] == ‘+‘) fixed[i][1] += 1 << j;       //fixed[i][1]某位为1表示apply后得到该漏洞
22         else if (s2[j] == ‘-‘) fixed[i][0] -= 1 << j;    //fixed[i][0]某位为0表示apply后修复该漏洞
23     }
24 }
25 void init()
26 {
27     cas ++;
28     maxn = (1 << n) - 1;
29     f[maxn] = 0; ha[maxn] = cas;
30     for (int i = 0; i < m; i++){
31         scanf("%d %s %s", &w[i], s1, s2);
32         cook_the_raw(i);
33     }
34 }
35 void spfa()
36 {
37     int head, tail;
38     head = tail = 0;
39     q[tail++] = maxn;
40     in[maxn] = true;
41     while (head != tail)
42     {
43         int u = q[head++];
44         if (head == maxq) head = 0;
45         for (int i = 0; i < m; i++){
46             if (((u & pre[i][1]) == pre[i][1]) && ((u & pre[i][0]) == 0)){  //满足patch[i]apply条件
47                 int v = (u | fixed[i][1]) & fixed[i][0];             //转移到的状态
48                 if (ha[v] != cas || f[v] > f[u] + w[i]){
49                     f[v] = f[u] + w[i]; ha[v] = cas;
50                     if  (!in[v]){
51                         q[tail++] = v;
52                         if (tail == maxq) tail = 0;
53                         in[v] = true;
54                     }
55                 }
56             }
57         }
58         in[u] = false;
59     }
60 }
61 void print()
62 {
63     printf("Product %d\n", cas);
64     if (ha[0] != cas) printf("Bugs cannot be fixed.\n\n");
65     else printf("Fastest sequence takes %d seconds.\n\n", f[0]);
66 }
67 int main()
68 {
69     memset(in, false, sizeof(in));
70     memset(ha, 0, sizeof(ha));
71     while(scanf("%d %d", &n, &m) && n+m)
72     {
73         init();
74         spfa();
75         print();
76     }
77     return 0;
78 }

POJ 1482 It's not a Bug, It's a Feature! 状压+spfa

时间: 2024-11-23 04:25:42

POJ 1482 It's not a Bug, It's a Feature! 状压+spfa的相关文章

It&amp;#39;s not a Bug, It&amp;#39;s a Feature! (poj 1482 最短路SPFA+隐式图+位运算)

Language: Default It's not a Bug, It's a Feature! Time Limit: 5000MS   Memory Limit: 30000K Total Submissions: 1353   Accepted: 516 Description It is a curious fact that consumers buying a new software product generally do not expect the software to

POJ 2288 Islands and Bridges(状压dp)

Language: Default Islands and Bridges Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 9312   Accepted: 2424 Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we all know, is a path along the b

POJ 2411 Mondriaan&#39;s Dream (状压+dfs)

Language: Default Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12405   Accepted: 7239 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in

poj 2411 Mondriaan&#39;s Dream(状压DP)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12232   Accepted: 7142 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

658 - It&#39;s not a Bug, it&#39;s a Feature! (Dijkstra算法)

今天第一次系统的学习了一下最短路算法,开始刷第十一章,第一次写Dijkstra算法,出现了很多喜闻乐见的错误..而且uva上样例很水,瓢虫也很水 ,坑了我好久. 首先是对于结点的处理,我们必须要维护一个二元组,一个表示结点一个表示当前结点最短路.   因为Dijkstra算法利用了优先队列来加速算法,所以需要定义小于运算符,一开始我直接将状态装进了优先队列,显然是不对的,因为优先队列的作用就是取出当前距离最短的结点. 其次,说说最短路算法蕴含的巧妙思想: 每次从当前所有还未标记的结点中选择一个距

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

poj 1699 Best Sequence(AC自动机+状压DP)

题目链接:poj 1699 Best Sequence 题目大意:给定N个DNA序列,问说最少多长的字符串包含所有序列. 解题思路:AC自动机+状压DP,先对字符串构造AC自动机,然后在dp[s][i]表示匹配了s,移动到节点i时候的最短步数. #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <iostream> #include &

POJ 1185 炮兵阵地 状压dp

http://poj.org/problem?id=1185 经典题目不必多说,直接贴代码. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n, m, cnt, size; 7 int a[110], st[70], ct[70]; 8 char str[15]; 9 int f[110][70][70]; 10 void init(

POJ 3254 Corn Fields 状压DP

链接:http://poj.org/problem?id=3254 题意:一块M*N的田地,每小块地大小是1*1,可以种植物的标记为1,不可以种植物的标记为0,并且相邻的两块地不可以同时种植物.问题是有多少种不同的种植方案(所有地都不种也是一种种植方案) 思路:这是第一道状压DP题,从第一行更新到最后一行,每一行用一个N位的二进制数来表示该行的状态1表示该位置种了植物,0表示该位置没种植物.因为每块地只对相邻的土地能否种植有所影响,所以每一行的状态可以用前一行的状态递推得到. 资料:http:/