zoukankan      html  css  js  c++  java
  • BZOJ 1001:[BeiJing2006]狼抓兔子(最小割)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1001

    题意:中文。

    思路:很明显是最小割,转化为最大流做。一开始看那么多点,但还是试了一下,居然过了。迷。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <queue>
     6 using namespace std;
     7 #define N 1000010
     8 #define INF 0x3f3f3f3f
     9 struct Edge {
    10     int v, cap, nxt;
    11 } edge[N*6];
    12 int head[N], cur[N], pre[N], tot, gap[N], dis[N], S, T;
    13 
    14 void Add(int u, int v, int cap) {
    15     edge[tot] = (Edge) {v, cap, head[u]}; head[u] = tot++;
    16     edge[tot] = (Edge) {u, cap, head[v]}; head[v] = tot++;
    17 }
    18 
    19 int BFS() {
    20     memset(gap, 0, sizeof(gap));
    21     memset(dis, INF, sizeof(dis));
    22     queue<int> que;
    23     que.push(T);
    24     dis[T] = 0; gap[0] = 1;
    25     while(!que.empty()) {
    26         int u = que.front(); que.pop();
    27         for(int i = head[u]; ~i; i = edge[i].nxt) {
    28             int v = edge[i].v;
    29             if(INF != dis[v]) continue;
    30             dis[v] = dis[u] + 1;
    31             gap[dis[v]]++;
    32             que.push(v);
    33         }
    34     }
    35 }
    36 
    37 int ISAP(int n) {
    38     BFS();
    39     memcpy(cur, head, sizeof(cur));
    40     int flow, ans = 0, u = pre[S] = S, i, index;
    41     while(dis[S] < n) {
    42         if(u == T) {
    43             flow = INF;
    44             for(i = S; i != T; i = edge[cur[i]].v)
    45                 if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
    46             for(i = S; i != T; i = edge[cur[i]].v)
    47                 edge[cur[i]].cap -= flow, edge[cur[i]^1].cap += flow;
    48             ans += flow; u = index;
    49         }
    50         for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap > 0 && dis[edge[i].v] == dis[u] - 1) break;
    51         if(~i) {
    52             cur[u] = i; pre[edge[i].v] = u; u = edge[i].v;
    53         } else {
    54             if(--gap[dis[u]] == 0) break;
    55             int md = n + 1;
    56             for(i = head[u]; ~i; i = edge[i].nxt)
    57                 if(edge[i].cap > 0 && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
    58             gap[dis[u] = md + 1]++;
    59             u = pre[u];
    60         }
    61     }
    62     return ans;
    63 }
    64 
    65 int main() {
    66     int n, m, w;
    67     scanf("%d%d", &n, &m);
    68     memset(head, -1, sizeof(head));
    69     tot = 0;
    70     for(int i = 0; i < n; i++)
    71         for(int j = 2; j <= m; j++)
    72             scanf("%d", &w), Add(j - 1 + i * m, j + i * m, w);
    73     for(int i = 1; i < n; i++)
    74         for(int j = 1; j <= m; j++)
    75             scanf("%d", &w), Add(j + (i - 1) * m, j + i * m, w);
    76     for(int i = 1; i < n; i++)
    77         for(int j = 2; j <= m; j++)
    78             scanf("%d", &w), Add(j - 1 + (i - 1) * m, j + i * m, w);
    79     S = 1, T = n * m;
    80     printf("%d
    ", ISAP(T + 1));
    81     return 0;
    82 }
  • 相关阅读:
    洛谷P3796 【模板】AC自动机(加强版)(AC自动机)
    洛谷P3203 [HNOI2010]弹飞绵羊(LCT,Splay)
    洛谷P1501 [国家集训队]Tree II(LCT,Splay)
    LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
    [BZOJ3172][TJOI2013]单词 AC自动机
    [BZOJ1968][AHOI2005]COMMON约数研究 数学
    [BZOJ1053][SDOI2005]反素数ant 数学
    [BZOJ1045][HAOI2008]糖果传递 数学
    [BZOJ2733][HNOI2012]永无乡 线段树合并
    [BZOJ1005][HNOI2008]明明的烦恼 数学+prufer序列+高精度
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6364578.html
Copyright © 2011-2022 走看看