• BZOJ3894 文理分科


    很明显的一道网络流题。。

    首先把所有值的加起来,再减掉网络流最小割值就好了,问题就是如何建图。这貌似也是考了好多次了的。。。

    把每个人抽象成一个点p,则

    先是S向p连边,流量为选文科的高兴值,p向T连边,流量为选理科的高兴值。

    然后是same的条件,对每个人新建两个点p1, p2

    S向p1连边,流量为文科same的高兴值,p1向相邻点和自己的p连边,流量为inf

    p2相T连边,流量为理科same的高兴值,相邻点和自己的p向p2连边,流量为inf

    然后跑一下网络流就好了(蒟蒻tot = 1没写调了半天还以为建图错了= =b)

      1 /**************************************************************
      2     Problem: 3894
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:1340 ms
      7     Memory:12924 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13  
     14 using namespace std;
     15 const int N = 3e4 + 10;
     16 const int M = 1e6 + 5;
     17 const int inf = 1e8;
     18 const int dx[5] = {0, 1, -1, 0, 0};
     19 const int dy[5] = {0, 0, 0, 1, -1};
     20  
     21 struct edge {
     22     int next, to, f;
     23     edge() {}
     24     edge(int _n, int _t, int _f) : next(_n), to(_t), f(_f) {}
     25 } e[M];
     26  
     27 int n, m, S, T, ans;
     28 int w[105][105], cnt_p;
     29 int first[N], tot = 1;
     30 int q[N], d[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) {
     45     e[++tot] = edge(first[x], y, f), first[x] = tot;
     46     e[++tot] = edge(first[y], x, 0), first[y] = tot;
     47 }
     48  
     49 #define y e[x].to
     50 #define p q[l]
     51 bool bfs() {
     52   int l, r, x;
     53   memset(d, -1, sizeof(d));
     54   d[q[1] = S] = 1;
     55   for (l = r = 1; l != r + 1; ++l)
     56     for (x = first[p]; x; x = e[x].next)
     57       if (!~d[y] && e[x].f) {
     58     d[q[++r] = y] = d[p] + 1;
     59     if (y == T) return 1;
     60       }
     61   return 0;
     62 }
     63 #undef p
     64  
     65 int dfs(int p, int lim) {
     66   if (p == T || !lim) return lim;
     67   int x, tmp, rest = lim;
     68   for (x = first[p]; x && rest; x = e[x].next) 
     69     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
     70       rest -= (tmp = dfs(y, tmp));
     71       e[x].f -= tmp, e[x ^ 1].f += tmp;
     72       if (!rest) return lim;
     73     }
     74   if (rest) d[p] = -1;
     75   return lim - rest;
     76 }
     77 #undef y
     78  
     79 inline int Dinic() {
     80   int res = 0;
     81   while (bfs())
     82     res += dfs(S, inf);
     83   return res;
     84 }
     85  
     86 inline bool in(int x, int y) {
     87     return x && y && x <= n && y <= m;
     88 }
     89  
     90 #define X i + dx[k]
     91 #define Y j + dy[k]
     92 #define p1(i, j) w[i][j] * 3
     93 #define p2(i, j) w[i][j] * 3 + 1
     94 #define p3(i, j) w[i][j] * 3 + 2
     95 int main() {
     96     int i, j, k, x;
     97     n = read(), m = read();
     98     for (i = 1; i <= n; ++i)
     99         for (j = 1; j <= m; ++j)
    100             w[i][j] = ++cnt_p;
    101     S = n * m * 3 + 3, T = S + 1;
    102     for (i = 1; i <= n; ++i)
    103         for (j = 1; j <= m; ++j)
    104             Add_Edges(S, p1(i, j), x = read()), ans += x;
    105     for (i = 1; i <= n; ++i)
    106         for (j = 1; j <= m; ++j)
    107             Add_Edges(p1(i, j), T, x = read()), ans += x;
    108     for (i = 1; i <= n; ++i)
    109         for (j = 1; j <= m; ++j) {
    110             Add_Edges(S, p2(i, j), x = read()), ans += x;
    111             for (k = 0; k <= 4; ++k)
    112                 if (in(X, Y)) Add_Edges(p2(i, j), p1(X, Y), inf);
    113         }
    114     for (i = 1; i <= n; ++i)
    115         for (j = 1; j <= m; ++j) {
    116             Add_Edges(p3(i, j), T, x = read()), ans += x;
    117             for (k = 0; k <= 4; ++k)
    118                 if (in(X, Y)) Add_Edges(p1(X, Y), p3(i, j), inf);
    119         }
    120     printf("%d
    ", ans - Dinic());
    121     return 0;
    122 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    网站制作常用的cms系统有哪些?
    企业网站建设中CMS系统的作用及现状
    PageAdmin企业网站制作中踩过的坑
    怎样制作网站的流程和步骤
    PageAdmin CMS建站系统可视化区块的使用教程
    PageAdmin CMS建站系统的可视化编辑体验
    企业网站建设常用CMS建站系统推荐
    PageAdmin CMS内容管理系统v4.0.11体验评测
    文本框检测回车按键或条码扫描结束回车符
    主播说联播 :铭记历史是为了创造历史 这三样东西不能丢!
  • 原文地址:https://www.cnblogs.com/rausen/p/4318846.html
Copyright © 2020-2023  润新知