• BZOJ2127 happiness


    很好的网络流题目啦,只不过有点烦,不过这下总算是完全掌握了Dinic的精髓。。。

    首先考虑建图:

    s --> A     权值为a[A] + sigma(他和四周都选全文科的高兴值) / 2

    A --> t     权值为b[A] + sigma(他和四周都选全理科的高兴值) / 2

    A <--> B  权值为(同时选文科的高兴值+同时选理科的高兴值) / 2

    为了解决精度问题,边权先乘以二,最后结果再除以二即可。

    但是不知道为什么是对的。。。在此Orz hzwer,要是没有他的程序我就完蛋了。。。

    (p.s. 作死小剧场增强版   我数组d一开始刚好开了d[10002],然后t=10002,死活过不了,查了一下午,我也是醉了%>_<%)

      1 /**************************************************************
      2     Problem: 2127
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:2472 ms
      7     Memory:6900 kb
      8 ****************************************************************/
      9   
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13   
     14 #define rep(i, n) for (int (i) = 1; (i) <= (n); ++(i))
     15 #define REP for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j)
     16 using namespace std;
     17 const int inf = (int) 1e9;
     18   
     19 struct edges{
     20     int next, to, f;
     21 } e[500000];
     22   
     23 int n, m, ans, tot = 1, s, t;
     24 int first[10005], q[10005], d[10005];
     25 int w[101][101], a[101][101], b[101][101];
     26   
     27 inline void add_edge(int x, int y, int z){
     28     e[++tot].next = first[x];
     29     first[x] = tot;
     30     e[tot].to = y;
     31     e[tot].f = z;
     32 }
     33   
     34 inline void add_Edge(int x, int y, int z){
     35     add_edge(x, y, z);
     36     add_edge(y, x, 0);
     37 }
     38   
     39 void add_Edges(int x, int y, int z){
     40     add_Edge(x, y, z);
     41     add_Edge(y, x, z);
     42 }
     43   
     44 bool bfs(){
     45     memset(d, 0, sizeof(d));
     46     q[1] = s, d[s] = 1;
     47     int l = 0, r = 1, x, y;
     48     while (l < r){
     49         ++l;
     50         for (x = first[q[l]]; x; x = e[x].next){
     51             y = e[x].to;
     52             if (!d[y] && e[x].f)
     53                 q[++r] = y, d[y] = d[q[l]] + 1;
     54         }
     55     }
     56     return d[t];
     57 }
     58   
     59 int dinic(int p, int limit){
     60     if (p == t || !limit) return limit;
     61     int x, y, tmp, rest = limit;
     62     for (x = first[p]; x; x = e[x].next){
     63         y = e[x].to;
     64         if (d[y] == d[p] + 1 && e[x].f && rest){
     65             tmp = dinic(y, min(rest, e[x].f));
     66             rest -= tmp;
     67             e[x].f -= tmp, e[x ^ 1].f += tmp;
     68             if (!rest) return limit;
     69         }
     70     }
     71     if (limit == rest) d[p] = 0;
     72     return limit - rest;
     73 }
     74   
     75 int Dinic(){
     76     int res = 0, x;
     77     while (bfs())
     78         res += dinic(s, inf);
     79     return res;
     80 }
     81   
     82 void make_graph(){
     83     int X;
     84     rep(i, n - 1) rep(j, m){
     85         scanf("%d", &X);
     86         ans += X, a[i][j] += X, a[i + 1][j] += X;
     87         add_Edges(w[i][j], w[i + 1][j], X);
     88     }
     89     rep(i, n - 1) rep(j, m){
     90         scanf("%d", &X);
     91         ans += X, b[i][j] += X, b[i + 1][j] += X;
     92         add_Edges(w[i][j], w[i + 1][j], X);
     93     }
     94     rep(i, n) rep(j, m - 1){
     95         scanf("%d", &X);
     96         ans += X, a[i][j] += X, a[i][j + 1] += X;
     97         add_Edges(w[i][j], w[i][j + 1], X);
     98     }
     99     rep(i, n) rep(j, m - 1){
    100         scanf("%d", &X);
    101         ans += X, b[i][j] += X, b[i][j + 1] += X;
    102         add_Edges(w[i][j], w[i][j + 1], X);
    103     }
    104     s =  n * m + 1, t = s + 1;
    105     REP{
    106         add_Edge(s, w[i][j], a[i][j]);
    107         add_Edge(w[i][j], t, b[i][j]);
    108     }
    109 }
    110   
    111 int main(){
    112     scanf("%d%d", &n, &m);
    113     REP{
    114         scanf("%d", a[i] + j);
    115         ans += a[i][j], a[i][j] <<= 1;
    116     }
    117     REP{
    118         scanf("%d", b[i] + j);
    119         ans += b[i][j], b[i][j] <<= 1;
    120     }
    121     REP w[i][j] = (i - 1) * m + j;
    122     make_graph();
    123     printf("%d
    ", ans - (Dinic() >> 1));
    124     return 0;
    125 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    css盒子模型之内边距padding及简写
    css盒子模型之宽度和高度
    windows 组策略
    windows 快捷键
    cmd 命令快捷键
    django 远程访问
    django 部署在 apache2 上面
    国内常用开源镜像站
    ubuntu1804自带官方源
    ubuntu1604 apt华为国内源
  • 原文地址:https://www.cnblogs.com/rausen/p/4003650.html
Copyright © 2020-2023  润新知