uva 658(Dijkstra)

题意:对于一个软件有若干个bug和若干个补丁告诉你打每个补丁需要的状态和打完后的状态还有打每个补丁的费用,让你求把软件修好的最小费用。

思路:这道就是就是最短路然后再加上状态压缩存储,把+号与-号分开存在两个变量中,然后在Dijkstra执行的时候把补丁看成边,软件状态看成点就行了,别的都一样。

代码如下:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <stack>
 8 #include <utility>
 9 #define ll long long
10 #define eps 1E-8
11 #define INF 5000001
12 #define LEN 111
13 
14 using namespace std;
15 
16 typedef pair<int, int> pii;
17 int n, m, vis[1<<21]; 
18 
19 struct V{
20     int val, bfix, bocr, efix, eocr;
21 };
22 
23 V vex[LEN];
24 
25 struct S{
26     int val, st;
27     bool operator<(const S b) const
28     {return val<b.val;}
29 };
30 
31 int BFS()
32 {
33     priority_queue<pii, vector<pii>, greater<pii> > q;
34     q.push(make_pair(0, (1<<n)-1));
35     while(!q.empty()){
36         pii nv= q.top(); q.pop();
37         if(nv.second==0) return nv.first;
38         if(vis[nv.second])continue;
39         vis[nv.second] = 1;
40         for(int i=0; i<m; i++){
41             pii xx = nv;
42             if((vex[i].bfix & xx.second)==vex[i].bfix && ((~xx.second) & vex[i].bocr)==vex[i].bocr){
43                 xx.second|=vex[i].efix;
44                 xx.second&=(~vex[i].eocr);
45                 xx.first += vex[i].val;
46                 q.push(xx);
47             }
48         }
49     }
50     return -1;
51 }
52 
53 int main()
54 {
55 //    freopen("in.txt", "r", stdin);
56 
57     char str[LEN];
58     int kase = 1;
59     while(scanf("%d%d", &n, &m)!=EOF){
60         if(n==0 && m==0) break;
61         memset(vex, 0, sizeof vex);
62         for(int i=0; i<m; i++){
63             scanf("%d%s", &vex[i].val, str);
64             for(int j=0; j<n; j++){
65                 if(str[j]=='+')vex[i].bfix |= (1<<j);
66             }
67             for(int j=0; j<n; j++){
68                 if(str[j]=='-')vex[i].bocr |= (1<<j);
69             }
70             scanf("%s", str);
71             for(int j=0; j<n; j++){
72                 if(str[j]=='+')vex[i].efix |= (1<<j);
73             }
74             for(int j=0; j<n; j++){
75                 if(str[j]=='-')vex[i].eocr |= (1<<j);
76             }
77         }
78         memset(vis, 0, sizeof vis);
79         int ans = -1;
80             ans = BFS();
81         printf("Product %d
", kase++);
82         if(ans == -1)printf("Bugs cannot be fixed.
");
83         else printf("Fastest sequence takes %d seconds.
", ans);
84         printf("
");
85     }
86     return 0;
87 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3475761.html