• BZOJ2597 [Wc2007]剪刀石头布


    什么鬼。。。冬令营题目不看题解能做?

    (看了题解也不会2333)

    其中有一部还是可以仔细思考一下的,就是对于费用流,如果每条边边满足:cost = a * flow2,如何做?

    我们可以拆边,新边上,每条边流量为1,费用为a * (x2 - (x - 1)2)(就是费用为a * (12 - 02), a * (22 - 12)...)

    拆边的思想还是很广泛的,恩...!

      1 /**************************************************************
      2     Problem: 2597
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:11144 ms
      7     Memory:10756 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13  
     14 using namespace std;
     15 const int Num = 105;
     16 const int N = Num * Num;
     17 const int M = 500005;
     18 const int inf = (int) 1e9;
     19  
     20 struct edges {
     21     int next, to, f, cost;
     22     edges() {}
     23     edges(int _n, int _t, int _f, int _c) : next(_n), to(_t), f(_f), cost(_c) {}
     24 } e[M];
     25   
     26 int tot = 1, first[N];
     27 int n, m, S, T;
     28 int in[Num], d[N], q[N], g[N];
     29 int sum[M];
     30 bool v[N];
     31  
     32 inline int read() {
     33     int x = 0;
     34     char ch = getchar();
     35     while (ch < '0' || '9' < ch)
     36         ch = getchar();
     37     while ('0' <= ch && ch <= '9') {
     38         x = x * 10 + ch - '0';
     39         ch = getchar();
     40     }
     41     return x;
     42 }
     43  
     44 inline void Add_Edges(int x, int y, int f, int c) {
     45     e[++tot] = edges(first[x], y, f, c), first[x] = tot;
     46     e[++tot] = edges(first[y], x, 0, -c), first[y] = tot;
     47 }
     48   
     49 inline int calc() {
     50     int flow = inf, x;
     51     for (x = g[T]; x; x = g[e[x ^ 1].to])
     52         flow = min(flow, e[x].f);
     53     for (x = g[T]; x; x = g[e[x ^ 1].to])
     54         e[x].f -= flow, e[x ^ 1].f += flow;
     55     return flow;
     56 }
     57   
     58 bool spfa() {
     59     int x, y, l, r;
     60     for (x = 1; x <= T; ++x)
     61         d[x] = inf;
     62     d[S] = 0, v[S] = 1, q[0] = S;
     63     for(l = r = 0; l != (r + 1) % N; ++l %= N) {
     64         for (x = first[q[l]]; x; x = e[x].next)
     65             if (d[q[l]] + e[x].cost < d[y = e[x].to] && e[x].f) {
     66                 d[y] = d[q[l]] + e[x].cost, g[y] = x;
     67                 if (!v[y])
     68                     q[++r %= N] = y, v[y] = 1;
     69             }
     70         v[q[l]] = 0;
     71     }
     72     return d[T] != inf;
     73 }
     74  
     75 inline int work() {
     76     int res = 0;
     77     while (spfa())
     78         res += calc() * d[T];
     79     return res;
     80 }
     81  
     82 void build_graph() {
     83     int i, j, x, now = 0;
     84     for (i = 1; i <= n; ++i)
     85         for (j = 1; j <= n; ++j) {
     86             x = read();
     87             if (j <= i) continue;
     88             sum[++now] = i + j;
     89             if (x == 2) {
     90                 Add_Edges(now, i + m, 1, 0), Add_Edges(now, j + m, 1, 0);
     91                 ++in[i], ++in[j];
     92             } else
     93             if (x == 1) Add_Edges(now, i + m, 1, 0), ++in[i];
     94             else Add_Edges(now, j + m, 1, 0), ++in[j];
     95         }
     96     for (i = 1; i <= m; ++i)
     97         Add_Edges(S, i, 1, 0);
     98     for (i = 1; i <= n; ++i)
     99         for (j = 1; j <= in[i]; ++j)
    100             Add_Edges(i + m, T, 1, 2 * j - 1);
    101 }
    102  
    103 void make_ans() {
    104     int a[Num][Num], i, j, x;
    105     memset(a, 0, sizeof(a));
    106     for (i = 1; i <= m; ++i)
    107         for (x = first[i]; x; x = e[x].next)
    108             if (!e[x].f) a[e[x].to - m][sum[i] - e[x].to + m] = 1;
    109     for (i = 1; i <= n; ++i) {
    110         for (j = 1; j <= n; ++j)
    111             printf("%d ", a[i][j]);
    112         printf("
    ");
    113     }
    114 }
    115  
    116 int main() {
    117     n = read(), m = n * (n - 1) / 2;
    118     S = n + m + 1, T = S + 1;
    119     build_graph();
    120     printf("%d
    ", (n * (n - 1) * (n - 2) / 3 + m - work()) / 2);
    121     make_ans();
    122     return 0;
    123 }
    View Code

    (p.s.  为何这么慢= =我去。。)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    mybatisplus-分页配置
    mybatisplus-逻辑删除配置
    python-字符串r、b、u、f
    python-pydantic-一个解析库
    python-class-一个type实例对象
    python-函数式编程&面向对象编程
    python-实例访问类属性的一个问题
    jmeter-取样器
    PSP总结报告
    20181204-1 每周例行报告
  • 原文地址:https://www.cnblogs.com/rausen/p/4197953.html
Copyright © 2020-2023  润新知