Petri Net Simulation

UVA 804 Petri Net Simulation

题意:对于一个变迁,需要多个入口满足,然后有多个出口。需要判断多次变迁之后是否这个网络还在运行。多个变迁任意进行一个不会对结果产生影响。

感谢:https://github.com/morris821028/UVa/blob/master/volume008/804%20-%20Petri%20Net%20Simulation.cpp

题解:解题思路方向正确思维不难。

但是作为模拟,如果打算从第一个开始往后走那一定是做不出来的。从一开始给的就有可能有多个可以变迁的方向考虑,我们遍历查询能够变迁的即可。

/*
author : mxylulu
date : 2019/2/21
says : 唯有全力以赴。
*/
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define RFOR(i,a,b) for(int i=a;i>=b;i--)
#define sf(i) scanf("%d",&i)
#define pf(i) printf("%d ",i)
using namespace std;

typedef long long LL;

int N,M,T;
int H[200];
vector<int>in[200];
vector<int>out[200];

void remove(int i)
{
    FOR(j,0,in[i].size()-1)
    {
        H[in[i][j]]--;
    }
}

void resume(int i)
{
    FOR(j,0,in[i].size()-1)
    {
        H[in[i][j]]++;
    }
}

bool check(int i)
{
    remove(i);
    bool ok=true;
    FOR(j,0,in[i].size()-1)
    {
        if(H[in[i][j]]<0)ok=false;
    }
    resume(i);
    return ok;
}

void action(int i)
{
    remove(i);
    FOR(j,0,out[i].size()-1)
    {
        H[out[i][j]]++;
    }
}

void simulate()
{
    FOR(i,1,T)
    {
        int update = 0;
        FOR(j,1,M)
        if(check(j))
        {
            update = 1;
            action(j);
            break;
        }
        if(!update)
        {
            printf("dead after %d transitions\n",i-1);
            return ;
        }
    }
    printf("still live after %d transitions\n",T);
}
int main()
{
    int cases = 0;
    cin>>N;
    while(N!=0)
    {
        ++cases;
        FOR(i,1,N)cin>>H[i];
        cin>>M;
        FOR(i,1,M)in[i].clear(),out[i].clear();
        FOR(i,1,M)
        {
            int temp;
            cin>>temp;
            while(temp!=0)
            {
                if(temp<0)in[i].push_back(-temp);
                else out[i].push_back(temp);
                cin>>temp;
            }
        }
        cin>>T;
        printf("Case %d: ",cases);
        simulate();
        printf("Places with tokens:");
        FOR(i,1,N)
        if(H[i])printf(" %d (%d)",i,H[i]);
        puts("\n");
        cin>>N;
    }
    //system("pause");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值