热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SCOI2012奇怪的游戏:结论与网络流应用

本题涉及一些特殊情况,例如黑白块数不相等的情况,这些情况不满足二分性质。对于有解的情况,可以通过特定公式直接计算出结果。本文将详细介绍如何使用网络流来解决这类问题。

在解决这个问题时,我们首先需要处理一些特殊情况,特别是当黑白块数不相等时,这些情况不满足二分性质。在这种情况下,可以直接通过公式计算出最终结果。

具体来说,如果存在解,则必须满足条件:x * cnt1 - ans1 == x * cnt0 - ans0,其中 x 是唯一解。

当黑白块数相等时,上述条件等价于 x = x,因此解的存在性可以通过检查当前 x 是否能够及时分配完成来判断。由于点与点之间的关系复杂,需要使用网络流算法。

需要注意的是,精度控制(eps)的设置非常重要。

以下是具体的代码实现:

#include 
#include 
#include 
#include 
using namespace std;
#define inf 1125899906842624
#define ll long long
queue q;
ll ans1, ans0, cnt1, cnt0, l, r, mid;
ll xia[2000], yuan[2000], tot, zhong[100000], v[1000000], hou[100000], T, n, m, i, j, s, t, d[55][55], dd[2000];

void add_edge(ll a, ll b, ll C) {
    ++tot;
    hou[tot] = yuan[a];
    yuan[a] = tot;
    zhong[tot] = b;
    v[tot] = C;
}

void add(ll a, ll b, ll C) {
    add_edge(a, b, C);
    add_edge(b, a, 0);
}

bool bfs() {
    for (int i = 1; i <= t; i++) {
        xia[i] = yuan[i];
        dd[i] = inf;
    }
    dd[s] = 0;
    q.push(s);
    while (!q.empty()) {
        int st = q.front();
        q.pop();
        for (int i = xia[st]; i != -1; i = hou[i]) {
            int nd = zhong[i];
            if (v[i] > 0 && dd[nd] == inf) {
                dd[nd] = dd[st] + 1;
                q.push(nd);
            }
        }
    }
    return dd[t] != inf;
}

ll dfs(int o, ll limit) {
    if (!limit || o == t) return limit;
    ll f = 0, flow = 0;
    for (int i = xia[o]; i != -1; i = hou[i]) {
        xia[o] = i;
        int nd = zhong[i];
        if (dd[nd] == dd[o] + 1 && (f = dfs(nd, min(limit, v[i])))) {
            flow += f;
            limit -= f;
            v[i] -= f;
            v[i ^ 1] += f;
            if (!limit) break;
        }
    }
    return flow;
}

ll dinic() {
    ll ans = 0;
    while (bfs()) {
        ans += dfs(s, inf);
    }
    return ans;
}

ll work(ll mid) {
    tot = -1;
    memset(yuan, -1, sizeof(yuan));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if ((i + j) & 1) {
                add(s, (i - 1) * m + j, mid - d[i][j]);
                if (i > 1) add((i - 1) * m + j, (i - 2) * m + j, inf);
                if (j > 1) add((i - 1) * m + j, (i - 1) * m + j - 1, inf);
                if (i = l && work((ans1 - ans0) / (cnt1 - cnt0)) == ((ans1 - ans0) / (cnt1 - cnt0)) * cnt1 - ans1) {
                printf("%lld\n", ((ans1 - ans0) / (cnt1 - cnt0)) * cnt1 - ans1);
            } else {
                printf("-1\n");
            }
        } else {
            if (ans0 != ans1) {
                printf("-1\n");
                continue;
            }
            while (l > 1;
                if (work(mid) == (mid * cnt1 - ans1)) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            printf("%lld\n", l * cnt1 - ans1);
        }
    }
}

推荐阅读
author-avatar
失意的汐_194
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有