UVA 804 Petri Net Simulation(算法竞赛入门经典,模拟)

算法竞赛入门经典177页,模拟
题目意思:
np个节点 p[1], p[2], … , p[np], 每个节点有若干个牌子 token, 节点与节点之间不直接联系,中间间隔了
一个叫 发射站 trans 的玩意。每一节点向外只能指向一个 发射站。并且,一个节点指向同一个发射站若干次,节点就需要若干个 token 。
发射站也是不能直接相连,
多个节点,可以同时指向一个发射站;
每一个发射站,可能指向若干个 节点。
一个发射站,是否能点火发射,主要看看这个发射站 Trans ,指向 Trans 的每一个节点,节点手中的牌子 token 是否足够。
只有所有的节点的 token 都足够,这个发射站才能点火。
点火之后,指向 发射站 Trans 的所有节点,会减少对应的 token ,而 发射站 Trans 指出的 节点, 这些节点的token 会增加对应的
token. 题目问:进过若干次点火,要么到达循环次数,要么就没有足够的 token 来点火。
此时,每一节点拥有的token数。

本题要点:
1、看懂题目意思,知道样例, 然后暴力模拟。
2、把题目的图画下来,走一下样例就知道了。本质是一道语文题。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int MaxN = 110;
int np, nt, cycle;
int pos[MaxN];	//pos[i]表示第i个 NP 的 token数量
int In[MaxN], Out[MaxN];

struct node
{
	int id, token;
};

struct NT
{
	vector<node> in, out;
}trans[MaxN];

bool check(int k)
{
	int len = trans[k].in.size(), token, id;
	for(int i = 0; i < len; ++i)
	{
		token = trans[k].in[i].token, id = trans[k].in[i].id;
		if(pos[id] < token)
			return false;
	}
	return true;
}

void handle(int k)
{
	int len = trans[k].in.size(), token, id;
	for(int i = 0; i < len; ++i)
	{
		token = trans[k].in[i].token, id = trans[k].in[i].id;
		pos[id] -= token;
	}
	len = trans[k].out.size();
	for(int i = 0; i < len; ++i)
	{
		token = trans[k].out[i].token, id = trans[k].out[i].id;
		pos[id] += token;
	}
}

void solve(int count)
{
	printf("Case %d: ", count);
	int cnt = 0;
	bool enough = false;
	while(true)
	{
		enough = false;
		for(int i = 1; i <= nt; ++i)
		{
			if(check(i))
			{
				handle(i);
				enough = true;
				++cnt;
				break;
			}
		}
		if(!enough)
			break;
		if(cnt >= cycle)
			break;
	}
	if(cnt >= cycle)
	{
		printf("still live after %d transitions\n", cycle);
	}else{
		printf("dead after %d transitions\n", cnt);
	}
	printf("Places with tokens:");
	for(int i = 1; i <= np; ++i)
	{
		if(pos[i])
			printf(" %d (%d)", i, pos[i]);
	}
	printf("\n\n");
}

int main()
{
	int id, count = 0;
	node tmp;
	while(scanf("%d", &np) != EOF && np)
	{
		for(int i = 0; i < MaxN; ++i)
		{
			trans[i].in.clear();
			trans[i].out.clear();
		}
		memset(pos, 0, sizeof pos);
		for(int i = 1; i <= np; ++i)
		{
			scanf("%d", &pos[i]);
		}
		scanf("%d", &nt);
		for(int i = 1; i <= nt; ++i)
		{
			memset(In, 0, sizeof In);
			memset(Out, 0, sizeof Out);
			while(scanf("%d", &id) && id)	
			{
				if(id < 0)
				{
					In[-id]++;				
				}else{
					Out[id]++;
				}
			}
			for(int j = 1; j <= np; ++j)
			{
				if(In[j])
				{
					tmp.id = j, tmp.token = In[j];	
					trans[i].in.push_back(tmp);
				}
				if(Out[j])
				{
					tmp.id = j, tmp.token = Out[j];
					trans[i].out.push_back(tmp);
				}
			}
		}
		scanf("%d", &cycle);
		solve(++count);
	}
	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
0
*/

/*
Case 1: still live after 100 transitions
Places with tokens: 1 (1)

Case 2: dead after 9 transitions
Places with tokens: 2 (1)
*/

猜你喜欢

转载自blog.csdn.net/qq_38232157/article/details/108345901