hihoCoder挑战赛12 永恒游戏 模拟

时间限制: 20000ms
单点时限: 1000ms
内存限制: 256MB

描述

很久很久以前,当Rowdark还是个善良的魔法师时,他在一个n个点m条边的无向图上玩一个游戏。

开始时他在一些点上放些石子。每次Rowdark选择一个点A,要求点A上的石子数大于等于邻居点个数。然后对A的每个邻居B,将A上的一个石子移到B上。如果不能选出这样的点A,那么游戏结束。Rowdark想知道这个游戏会不会无限循环。为了使问题更简单,你只需要求出是否10万轮后游戏仍然继续。

输入

第一行两个整数n和m(1 ≤ n ≤ 200)。

第二行n个整数a0, a1 ... an-1表示每个点上的石子个数(0 ≤ ai ≤ 109)。

接下来m行,每行两个数x和y (x ≠ y, 0 ≤ x, y ≤ n - 1),表示在x和y之间有一条边。题目保证没有重边,且任意一个点都有邻居。

输出

如果Rowdark能玩超过100000轮,输出“INF”(不带引号),否则输出最多步数。

样例输入
3 3
1 2 1
0 1
1 2
2 0
样例输出
INF

#include <iostream>
#include <vector>

using namespace std;

int n,m;

int choose(vector<int>& shitou, vector<vector<bool>> &map, vector<int> &nei) {
    for(int i = 0; i < n; ++i) {
        if(shitou[i] >= nei[i]) {
            for(int j = 0; j < n; ++j) {
                if(j == i) continue;
                if(map[i][j] == true) {
                    shitou[j]++;
                    shitou[i]--;
                }
            }
            return i;
        }
    }
    return -1;
}

int main() {
    cin>>n>>m;
    int MAX = 100000;
    int cases = 0;
    int x = 0;
    int xx, yy;
    int num = -1;
    bool flag = true;
    vector<int> shitou;
    vector<vector<bool>> map(n,vector<bool>(n,false));
    vector<int> nei(n, 0);
    for(int i = 1; i <= n; ++i) {
        cin>>x;
        shitou.push_back(x);
    }
    for(int i = 1; i <= m; ++i) {
        cin>>xx>>yy;
        map[xx][yy] = true;
        map[yy][xx] = true;
    }
    for(int i = 0; i < n; ++i) {
        //calculate neighbor's geshu
        for(int j = 0; j < n; ++j) {
            if(j == i) continue;
            if(map[i][j] == true) {
                nei[i]++;
            }
        }
    }
    for(int i = 1; i <= MAX; ++i) {
        num = choose(shitou, map, nei);
        if(num == -1) {
            flag = false;
            break;
        }
        cases++;
    }
    if(flag == false) {
        cout<<cases<<endl;
    }else {
        cout<<"INF"<<endl;
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值