?? 1620.cpp
字號:
/* This Code is Submitted by wywcgs for Problem 1620 on 2006-09-02 at 15:24:14 */
#include <cstdio>
#include <algorithm>
using namespace std;
const int AN = 32;
const int MP = 128, MB = 32;
const int SN = 1 << 20;
const int INF = 1 << 29;
class FibNode {
public:
bool mark;
int left, right, p, child;
int degree, key, st;
void set(int s, int k) { mark = false; left = right = st = s; p = child = -1; degree = 0; key = k; }
};
class FibHeap {
private:
FibNode h[SN];
bool pos[SN];
int head, minH, size;
void addToRootList(int);
void eraseFromRootList(int);
void link(int, int);
void consolidate();
void cut(int, int);
void cascading(int);
public:
void clear(int);
bool isEmpty() const { return size == 0; }
void insert(int, int);
FibNode minNode() const { return h[minH]; }
FibNode extractMin();
void decreaseKey(int, int);
void deleteE(int x) { decreaseKey(x, -INF); extractMin(); }
};
void FibHeap::addToRootList(int x) {
if(head == -1) head = x;
else {
int a = h[head].right, b = h[x].left;
h[head].right = x; h[x].left = head;
h[b].right = a; h[a].left = b;
}
}
void FibHeap::eraseFromRootList(int x) {
if(x == h[x].right) head = -1;
else {
if(head == x) head = h[x].right;
h[h[x].right].left = h[x].left;
h[h[x].left].right = h[x].right;
}
}
void FibHeap::link(int x, int y) {
if(h[x].child == -1) { h[x].child = y; h[y].left = h[y].right = y; }
else {
int a = h[h[x].child].right;
h[h[x].child].right = y; h[y].left = h[x].child;
h[y].right = a; h[a].left = y;
}
h[y].p = x; h[y].mark = false; h[x].degree++;
}
void FibHeap::consolidate() {
int a[AN], dlmt = 0;
memset(a, -1, sizeof(a));
while(head != -1) {
int x = head; eraseFromRootList(x);
int d = h[x].degree;
h[x].p = -1;
while(a[d] != -1) {
int y = a[d];
if(h[x].key > h[y].key) swap(x, y);
link(x, y); a[d] = -1; d++;
}
a[d] = x; dlmt >?= d+1;
}
minH = -1;
for(int i = 0; i < dlmt; i++) {
if(a[i] == -1) continue;
h[a[i]].left = h[a[i]].right = a[i];
addToRootList(a[i]);
if(minH == -1 || h[a[i]].key < h[minH].key) minH = a[i];
}
}
void FibHeap::clear(int sn) {
size = 0;
head = minH = -1;
memset(pos, false, sizeof(bool)*sn);
}
void FibHeap::insert(int x, int v) {
h[x].set(x, v);
addToRootList(x); size++;
pos[x] = true;
if(minH == -1 || h[minH].key > v) minH = x;
}
FibNode FibHeap::extractMin() {
FibNode r = h[minH];
int x = minH;
if(h[x].child != -1) addToRootList(h[x].child);
eraseFromRootList(x); size--;
if(x == h[x].right) minH = -1;
else consolidate();
pos[r.st] = false;
return r;
}
void FibHeap::decreaseKey(int x, int v) {
if(!pos[x]) { insert(x, v); return; }
else if(h[x].key <= v) return;
h[x].key = v;
int y = h[x].p;
if(y != -1 && h[x].key < h[y].key) { cut(x, y); cascading(y); }
if(v < h[minH].key) minH = x;
}
void FibHeap::cut(int x, int y) {
if(x == h[x].right) h[y].child = -1;
else {
if(h[y].child == x) h[y].child = h[x].right;
h[h[x].right].left = h[x].left;
h[h[x].left].right = h[x].right;
h[x].left = h[x].right = x;
}
h[y].degree--;
addToRootList(x);
h[x].p = -1; h[x].mark = false;
}
void FibHeap::cascading(int y) {
int z = h[y].p;
if(z == -1) return;
else if(!h[y].mark) h[y].mark = true;
else { cut(y, z); cascading(z); }
}
class Patch {
public:
int pre, abs, fix, intro, cost;
void build(int);
};
void Patch::build(int n) {
char con[MB], fixed[MB];
scanf("%d %s %s", &cost, con, fixed);
pre = abs = fix = intro = 0;
for(int i = 0; i < n; i++) {
if(con[i] == '+') pre |= 1 << i;
else if(con[i] == '-') abs |= 1 << i;
if(fixed[i] == '-') fix |= 1 << i;
else if(fixed[i] == '+') intro |= 1 << i;
}
fix ^= (1<<n)-1;
}
FibHeap heap;
Patch patch[MP];
int n, m, pop[SN] = { 0 };
int Dijkstra(int);
int main()
{
for(int t = 1; scanf("%d %d", &n, &m) != EOF && n != 0; t++) {
for(int i = 0; i < m; i++) patch[i].build(n);
int time = Dijkstra(t);
printf("Product %d\n", t);
if(time == INF) printf("Bugs cannot be fixed.\n\n");
else printf("Fastest sequence takes %d seconds.\n\n", time);
}
return 0;
}
int Dijkstra(int t)
{
int sn = 1<<n, time = INF;
heap.clear(sn); heap.insert(sn-1, 0);
while(!heap.isEmpty()) {
FibNode bug = heap.extractMin();
pop[bug.st] = t;
if(bug.st == 0) { time = bug.key; break; }
for(int i = 0; i < m; i++)
if((bug.st&patch[i].abs) == 0 && (bug.st&patch[i].pre) == patch[i].pre) {
int st = (bug.st&patch[i].fix)|patch[i].intro;
if(pop[st] == t) continue;
heap.decreaseKey(st, bug.key+patch[i].cost);
}
}
return time;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -