[luoguP2761] 软件补丁问题(状压最短路)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP2761] 软件补丁问题(状压最短路)相关的知识,希望对你有一定的参考价值。

传送门

 

n <= 20 很小

所以可以状态压缩

然后因为可能存在环,所以不能DP

那么就用spfa找最短路

 

被位运算坑了,不清楚优先级一定要加括号

 

——代码

技术分享
 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #define M 301
 6 #define N 4000001
 7 
 8 int n, m;
 9 int b1[M], b2[M], f1[M], f2[M], a[M], dis[N];
10 bool vis[N];
11 
12 inline void spfa()
13 {
14     int i, v, u;
15     std::queue <int> q;
16     memset(dis, 0x33, sizeof(dis));
17     q.push((1 << n) - 1);
18     dis[(1 << n) - 1] = 0;
19     while(!q.empty())
20     {
21         u = q.front(), q.pop();
22         vis[u] = 0;
23         for(i = 1; i <= m; i++)
24             if((u | b1[i]) == u && !(u & b2[i]))
25             {
26                 v = u ^ (u & f1[i]) | f2[i];
27                 if(dis[v] > dis[u] + a[i])
28                 {
29                     dis[v] = dis[u] + a[i];
30                     if(!vis[v])
31                     {
32                         q.push(v);
33                         vis[v] = 1;
34                     }
35                 }
36             }
37     }
38 }
39 
40 int main()
41 {
42     int i, j;
43     char s1[M], s2[M];
44     scanf("%d %d", &n, &m);
45     for(i = 1; i <= m; i++)
46     {
47         scanf("%d %s %s", &a[i], s1, s2);
48         for(j = 0; j < n; j++)
49         {
50             if(s1[j] == +) b1[i] |= 1 << j;
51             if(s1[j] == -) b2[i] |= 1 << j;
52             if(s2[j] == -) f1[i] |= 1 << j;
53             if(s2[j] == +) f2[i] |= 1 << j;
54         }
55     }
56     spfa();
57     dis[0] == dis[1 << n] ? puts("0") : printf("%d\n", dis[0]);
58     return 0;
59 }
View Code

 

以上是关于[luoguP2761] 软件补丁问题(状压最短路)的主要内容,如果未能解决你的问题,请参考以下文章

luogu2761 软件补丁问题

[luoguP2622] 关灯问题II(状压最短路)

P2761 软件补丁问题

洛谷 P2761 软件补丁问题 spfa

网络流24题软件补丁问题(最短路)

[网络流24题] 软件补丁问题