1426E

    科技2026-04-25  12

    1426E.Rock, Paper, Scissors

    Description

    Analysis

    题意概述

    两个玩家共玩 n n n ( 1 ≤ n ≤ 1 0 9 ) (1\le n\le10^9) (1n109)石头剪刀布,给出其分别出石头、剪刀、布的次数

    求玩家 1 1 1 最少或最多可能的获胜次数

    分析(基于 M C M F MCMF MCMF 的解法)

    (看到 f l o w flow flow 的标签就直接上网络流了,简单琢磨了一下建图方式,没有标签以作者目前的实力可能无法 a c ac ac

    最小费用最大流 a n d and and 最大费用最大流(分别对应最少获胜次数和最多获胜次数)

    建图分析

    源点 S → 0 S\to0 S0,汇点 T → 7 T\to7 T7玩家 1 1 1 a 1 , a 2 , a 3 → a_1,a_2,a_3\to a1,a2,a3 剪刀、石头、布 → \to 节点 1 , 2 , 3 1,2,3 1,2,3玩家 2 2 2 b 1 , b 2 , b 3 → b_1,b_2,b_3\to b1,b2,b3 剪刀、石头、布 → \to 节点 4 , 5 , 6 4,5,6 4,5,6

    S S S 向玩家 1 1 1 的对应节点连接一条容量为 a i a_i ai,费用为 0 0 0 的边

    玩家 2 2 2 的对应节点向 T T T 连接一条容量为 b i b_i bi,费用为 0 0 0 的边

    玩家 1 1 1 的对应节点向玩家 2 2 2 的对应节点连接一条容量为 ∞ \infin 的边,费用:平局/负: 0 0 0,胜利: 1 1 1

    原网络的每一个可行流,对应一场合法的游戏,总费用即为玩家 1 1 1 的胜利次数

    以此,求最小费用最大流 a n d and and 最大费用最大流即可

    Code

    #include <iostream> #include <cstring> #include <algorithm> using namespace std; constexpr const int N = 10, M = 40, inf = 0x3f3f3f3f; int h[N], e[M], ne[M], w[M], f[M], idx; int dist[N], d[N], pre[N], q[N], hh, tt; bool st[N]; int n, S, T, x, flow, cost; void add(int a, int b, int c, int d) { e[idx] = b, f[idx] = c, w[idx] = d, ne[idx] = h[a], h[a] = idx++; e[idx] = a, f[idx] = 0, w[idx] = -d, ne[idx] = h[b], h[b] = idx++; } bool spfa() { memset(d, 0, sizeof d); memset(dist, 0x3f, sizeof dist); hh = 0, tt = 1; q[0] = S, d[S] = inf, dist[S] = 0; while(hh != tt){ int u = q[hh++]; if(hh == N) hh = 0; st[u] = 0; for(int i = h[u]; ~i; i = ne[i]){ int j = e[i]; if(f[i] && dist[j] > dist[u] + w[i]){ dist[j] = dist[u] + w[i]; d[j] = min(d[u], f[i]); pre[j] = i; if(!st[j]){ st[j] = 1; q[tt++] = j; if(tt == N) tt = 0; } } } } return d[T] > 0; } void EK(int& flow, int& cost) { flow = cost = 0; while(spfa()) { flow += d[T], cost += dist[T] * d[T]; for(int i = T; i != S; i = e[pre[i] ^ 1]) f[pre[i]] -= d[T], f[pre[i] ^ 1] += d[T]; } } int main() { cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); cin >> n; memset(h, -1, sizeof h); S = 0, T = 7; for(int i = 1; i <= 3; i++) { cin >> x; add(S, i, x, 0); add(i, i + 3, inf, 0); } for(int i = 1; i <= 3; i++) { cin >> x; add(i + 3, T, x, 0); } add(1, 5, inf, 1); add(1, 6, inf, 0); add(2, 4, inf, 0); add(2, 6, inf, 1); add(3, 4, inf, 1); add(3, 5, inf, 0); EK(flow, cost); cout << cost << " "; for(int i = 0; i < idx; i += 2) { f[i] += f[i ^ 1], f[i ^ 1] = 0; w[i] = -w[i], w[i ^ 1] = -w[i ^ 1]; } EK(flow, cost); cout << -cost << '\n'; return 0; }
    Processed: 0.010, SQL: 10