- 传送门 -
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=599
细节见代码.
PS:
dijkstra慢如狗...用SPFA的快如闪电
- 代码 -
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 20;
const int M = 100 + 5;
const int inf = 0x3f3f3f3f;
struct point {
int bug, dist;
bool operator < (const point &y) const {
return dist > y.dist;
//priority_queue维护大根堆, 重定义'<', 插入的数比父亲小则满足条件, 往上交换...其实没有搞懂...以后还是用pair好了
}
};
priority_queue<point> Q;
int TI[M], VIS[(1<<N) + 5], DIS[(1<<N) + 5];
char BG[M][25], ED[M][25];
int n, m;
int dijkstra() {
for (int i = 0; i < (1<<N); ++i) {
VIS[i] = 0;
DIS[i] = inf;
}
while (!Q.empty())
Q.pop();
point st;
st.bug = (1 << n) - 1;
st.dist = 0;
DIS[st.bug] = 0;
Q.push(st);
while (!Q.empty()) {
point x = Q.top();
Q.pop();
if (VIS[x.bug]) continue;
VIS[x.bug] = 1;
if (!x.bug) return x.dist;
for (int i = 1; i <= m; ++i) {
bool flag = true;
for (int j = 0; j < n; ++j) {
if (BG[i][j] == '-' && (x.bug&(1<<j))) { flag = false; break; }
if (BG[i][j] == '+' && !(x.bug&(1<<j))) { flag = false; break; }
}
if (!flag) continue;
point y = x;
y.dist += TI[i];
for (int j = 0; j < n; ++j) {
if (ED[i][j] == '-') y.bug &= ~(1<<j);
if (ED[i][j] == '+') y.bug |= (1<<j);
}
if (!VIS[y.bug] && y.dist < DIS[y.bug]) {
DIS[y.bug] = y.dist;
Q.push(y);
}
}
}
return -1;
}
int main() {
int cas = 0;
while (scanf("%d%d", &n, &m) != EOF && n && m) {
// if (cas) printf("
");
// cas++;
printf("Product %d
", ++cas);
for (int i = 1; i <= m; ++i)
scanf("%d%s%s", &TI[i], BG[i], ED[i]);
int ans = dijkstra();
if (ans == -1) printf("Bugs cannot be fixed.
");
else printf("Fastest sequence takes %d seconds.
", ans); //uva再次玄学格式
}
return 0;
}