版权声明:欢迎转载!拒绝抄袭. https://blog.csdn.net/qq_36257146/article/details/88594102
这道题的关键是二进制的或与运算~
现在特别感激计算机基础的老师给了我们做bomb实验,受益匪浅。
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define maxm 105
#define maxn ((1<<20)+1)
using namespace std;
struct Node
{
int u,d;
Node(int i,int j):u(i),d(j){}
Node(){}
bool operator < (const Node & a)const
{
return d>a.d;
}
};
int n,m;
int c[maxm];//代价
int d[maxn];//距离
bool vis[maxn];
string s1[maxm],s2[maxm];//补丁
//是否匹配补丁
bool match(int u,int i)
{
for(int j = 0;j<s1[i].size();j++)
{
if(s1[i][j]=='+') if(!(u&(1<<j))) return false;
if(s1[i][j]=='-') if(u&(1<<j)) return false;
}
return true;
}
//打完补丁后的状态
int change(int u,int i)
{
//cout<<s2[i].size()<<endl;
for(int j = 0;j<s2[i].size();j++)
{
if(s2[i][j]=='+') u = u|(1<<j);
if(s2[i][j]=='-') u = u&(~(1<<j));
}
return u;
}
int dijkstra()
{
priority_queue<Node>Q;
memset(vis,0, sizeof(vis));
memset(d,INF, sizeof(d));
int u = (1<<n)-1;//初始状态++
d[u] = 0;
Q.push(Node(u,0));
while (!Q.empty())
{
Node x = Q.top();Q.pop();
u = x.u;
if(vis[u]) continue;
vis[u] = 1;
if(u == 0) return d[u];//已经找到了
for(int i = 0;i<m;i++)
{
if(match(u,i))
{
int v = change(u,i);//新的状态
if(d[v]>d[u]+c[i])
{
d[v] = d[u]+c[i];
Q.push(Node(v,d[v]));
}
}
}
}
return -1;
}
int main() {
int cost;
int kase = 0;
while (cin>>n>>m&&n+m)
{
for(int i = 0;i<m;i++)
{
cin>>c[i]>>s1[i]>>s2[i];
}
int ans = dijkstra();
//if(kase++) cout<<endl;
printf("Product %d\n",++kase);
if(ans!=-1)
printf("Fastest sequence takes %d seconds.\n\n",ans);
else
printf("Bugs cannot be fixed.\n\n");
}
return 0;
}
/**
3 3
1 000 00-
1 00- 0-+
2 0-- -++
4 1
7 0-0+ ----
0 0
**/