uva 804 Petri Net 模拟

原题

普通的模拟题, 题目虽然比较长但流程还是比较简单的, 所以主要还是几个细节的问题处理好就行了。

注意如果所给数据只能进行N轮循环, 而要求的循环数NF正好等于N时,执行完N轮退出时的状态仍然是alive,虽然下一步已经没有操作可做了。

奇怪的是一开始不知道为啥超时了,然后似乎没改进什么复杂度只改了几个细节再交上去就AC了。。。

以下为AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <cassert>
#include <iomanip>

#pragma warning(disable:4996) //关掉4996警告

/*
Uva 804  佩特里网络模拟

*/

using namespace std;

struct Transit {
    vector<int> from;
    vector<int> to;
};
vector<int> Places(1024);
vector<Transit> Transits(1024);

int NT, NP, NF, Case = 0;

inline bool isAlive(int n) {
    bool isEnable = true;
    map<int, int> need;
    for ( int j = 0; j < Transits[n].from.size( ); j++ ) {
        need[Transits[n].from[j]] += 1;
        if ( Places[Transits[n].from[j]] < need[Transits[n].from[j]] ) {
            isEnable = false;
            break;
        }
    }
    return isEnable;
}

int Simulate(int times, bool & alive) {
    int tmp = times;
    while ( times-- ) {
        int i = 0;
        for ( i = 1; i <= NT; i++ ) {
            if ( isAlive(i) ) {
                for ( int j = 0; j < Transits[i].from.size( ); j++ ) {
                    Places[Transits[i].from[j]]--;
                }
                for ( int j = 0; j < Transits[i].to.size( ); j++ ) {
                    Places[Transits[i].to[j]]++;
                }
                break;                              // 完成一次Trans
            }
        }
        if ( i > NT ) {
            alive = false;
            break;          // Dead
        }
    }
    return (tmp - (times + 1));
}

int main( ) {
    //freopen("input.txt", "r", stdin);
    //freopen("VSoutput.txt", "w", stdout);
    while ( cin >> NP && NP > 0 ) {
        Places.clear( );
        Transits.clear( );
        Places.resize(1024);
        for ( int i = 1, tmp; i <= NP; i++ ) {
            cin >> tmp;
            Places[i] = tmp;
        }
        cin >> NT;
        Transits.resize(1024);
        for ( int i = 1, tmp; i <= NT; i++ ) {
            while ( cin >> tmp && tmp != 0 ) {
                if ( tmp < 0 ) Transits[i].from.push_back(-tmp);
                else Transits[i].to.push_back(tmp);
            }
        }
        cin >> NF;
        bool alive = true;
        int turns = Simulate(NF, alive);
        printf("Case %d: %s after %d transitions\n",
               ++Case, (alive ? "still live" : "dead"), turns);
        printf("Places with tokens:");
        for ( int i = 1; i <= NP; i++ ) {
            if ( Places[i] ) {
                printf(" %d (%d)", i, Places[i]);
            }
        }
        cout << endl << endl;
    }
    //system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值