UVa 804 - Petri Net Simulation

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

上網搜尋 Petri Net ,得到是一個輸入輸出端的操作,當輸入端都至少一個時,將會進行觸發,每一次觸發會將輸入端都少一個元素,而輸出端會多一個元素。

現在模擬轉換 n 次,每一次轉換只能觸發一條,保證最終停留的結果只有一種,而當轉換失敗時,則宣告死亡。

Sample Input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
1 0
2
-1 2 0
-2 1 0
100
3
3 0 0
3
-1 2 0
-2 -2 3 0
-3 1 0
100
3
1 0 0
3
-1 2 3 0
-2 1 0
-3 1 0
1
0

Sample Output

1
2
3
4
5
6
7
8
Case 1: still live after 100 transitions
Places with tokens: 1 (1)
Case 2: dead after 9 transitions
Places with tokens: 2 (1)
Case 3: still live after 1 transitions
Places with tokens: 2 (1) 3 (1)

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdio.h>
#include <map>
#include <queue>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 1024
#define MAXM 1024
int N, P[MAXN], M, K;
vector<int> INPUT[MAXM], OUTPUT[MAXM];
void remove(int tid) {
for (int i = 0; i < INPUT[tid].size(); i++) {
P[INPUT[tid][i]]--;
}
}
void resume(int tid) {
for (int i = 0; i < INPUT[tid].size(); i++) {
P[INPUT[tid][i]]++;
}
}
int trigger(int tid) {
int ok = 1;
remove(tid);
for (int i = 0; i < INPUT[tid].size(); i++)
ok &= P[INPUT[tid][i]] >= 0;
resume(tid);
return ok;
}
void action(int tid) {
remove(tid);
for (int i = 0; i < OUTPUT[tid].size(); i++)
P[OUTPUT[tid][i]]++;
}
void simulate() {
for (int i = 0; i < K; i++) {
int update = 0;
for (int j = 0; j < M; j++) {
if (trigger(j)) {
update = 1;
action(j);
break;
}
}
if (!update) {
printf("dead after %d transitions\n", i);
return;
}
}
printf("still live after %d transitions\n", K);
}
int main() {
int cases = 0;
while (scanf("%d", &N) == 1 && N) {
for (int i = 1; i <= N; i++)
scanf("%d", &P[i]);
scanf("%d", &M);
for (int i = 0; i < M; i++) {
int x;
INPUT[i].clear(), OUTPUT[i].clear();
while (scanf("%d", &x) == 1 && x) {
if (x < 0)
INPUT[i].push_back(-x);
if (x > 0)
OUTPUT[i].push_back(x);
}
}
scanf("%d", &K);
printf("Case %d: ", ++cases);
simulate();
printf("Places with tokens:");
for (int i = 1; i <= N; i++) {
if (P[i])
printf(" %d (%d)", i, P[i]);
}
puts("\n");
}
return 0;
}
/*
2
1 0
2
-1 2 0
-2 1 0
100
3
3 0 0
3
-1 2 0
-2 -2 3 0
-3 1 0
100
3
1 0 0
3
-1 2 3 0
-2 1 0
-3 1 0
1
0
*/