Uva--658(图论,最短路,bit)

本文介绍了一个使用SPFA算法解决特定问题的例子。通过该算法找出修复bug的最快序列,包括了状态压缩、队列操作等关键步骤。代码示例清晰地展示了如何通过输入不同条件来求解最短路径。

2014-09-12 11:51:10

思路:不想说了,把int型数组开成了char - = 哭死。 参考

 

 1 /*************************************************************************
 2     > File Name: 658.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Thu 11 Sep 2014 06:46:03 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <queue>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 typedef long long ll;
18 const int INF = 1 << 30;
19 const int RA = 1 << 20;
20 
21 int Case = 0,n,m,w[105],maxn;
22 int s1[2][105],s2[2][105];
23 int d[RA + 5],inq[RA + 5];
24 
25 void Spfa(){
26     maxn = 1 << n;
27     int s = maxn - 1;
28     memset(inq,0,sizeof(inq));
29     for(int i = 0; i < maxn; ++i) d[i] = INF;
30     d[s] = 0;
31     queue<int> q; while(!q.empty()) q.pop();
32     q.push(s);
33     inq[s] = 1;
34     while(!q.empty()){
35         int x = q.front(); q.pop();
36         inq[x] = 0;
37         for(int i = 0; i < m; ++i)    if((x | s1[1][i]) == x && (x & s1[0][i]) == x){
38             int y = x;
39             y |= s2[1][i];
40             y &= s2[0][i];
41             if(d[y] > d[x] + w[i]){
42                 d[y] = d[x] + w[i];
43                 if(!inq[y]){
44                     inq[y] = 1;
45                     q.push(y);
46                 }
47             }
48         }
49     }
50     if(d[0] == INF) printf("Bugs cannot be fixed.\n");
51     else printf("Fastest sequence takes %d seconds.\n",d[0]);
52 }
53 
54 int main(){
55     char a[105],b[105];
56     while(scanf("%d%d",&n,&m) != EOF && (n || m)){
57         memset(s1,0,sizeof(s1));
58         memset(s2,0,sizeof(s2));
59         for(int i = 0; i < m; ++i){
60             scanf("%d%s%s",&w[i],a,b);
61             for(int j = 0; j < n; ++j){
62                 if(a[j] == '+') s1[1][i] |= (1 << j);
63                 if(a[j] != '-') s1[0][i] |= (1 << j);
64                 if(b[j] == '+') s2[1][i] |= (1 << j);
65                 if(b[j] != '-') s2[0][i] |= (1 << j);
66             }
67         }
68         printf("Product %d\n",++Case);
69         Spfa();
70         puts("");
71     }
72     return 0;
73 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/3968104.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值