一开始没好好读题。。漏了一个很重要的地方:当每个变迁的每个输入库所都至少有一个token时,变迁是允许的。变迁发生的结果是每个输入库所减少一个token,每个输出库所增加一个token。 注意是每一个啊~~
我写了个结构体,结构体里有两个映射成员,分别表示这个变迁的输入库和输出库。键表示序号,值表示需要的token个数。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100+9;
int n,m,a[maxn],cnt,ans,bbs=0;
struct net{
map<int,int> inp;
map<int,int>outp;
};
int main() {
while(scanf("%d",&n)!=EOF&&n) {
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
net s[maxn];
for(int i=1;i<=m;i++){
while(scanf("%d",&ans)!=EOF) {
if(ans==0) break;
else if(ans<0) {
if(!s[i].inp.count(-ans)) s[i].inp[-ans]=1;
else s[i].inp[-ans]++;
}
else {
if(!s[i].outp.count(ans)) s[i].outp[ans]=1;
else s[i].outp[ans]++;
}
}
}
scanf("%d",&cnt);
int kase=0;
map<int,int> ::iterator it;
while(1) {
bool flage=false;
for(int i=1;i<=n;i++){
if(a[i]!=0){
for(int j=1;j<=m;j++){
if(s[j].inp.count(i)&&s[j].inp[i]<=a[i]) {
flage=true;
for(it=s[j].inp.begin();it!=s[j].inp.end();++it)
if(a[(*it).first]<(*it).second) flage=false;
if(flage)
for(it=s[j].inp.begin();it!=s[j].inp.end();++it)
a[(*it).first]-=(*it).second;
for(it=s[j].outp.begin();it!=s[j].outp.end();++it)
a[(*it).first]+=(*it).second;
break;
}
}
}
if(flage) break;
}
if(flage) {
kase++;
if(kase>=cnt) break;
}
else break;
}
if(kase==cnt) printf("Case %d: still live after %d transitions\n",++bbs,cnt);
else printf("Case %d: dead after %d transitions\n",++bbs,kase);
printf("Places with tokens:");
for(int i=1;i<=n;i++)
if(a[i]!=0) printf(" %d (%d)",i,a[i]);
printf("\n\n");
}
return 0;
}