• [BeiJing2006]狼抓兔子


    题面

    一眼看就是最小割板子题,建图也很直观,注意每一条边建双向边其实不用建4条边,只要反向边的容量和正边相同就行。然后直接跑最大流板子就行。不过此题拿vector存图会MLE……而拿链前存图就能卡过去……场面一度十分尴尬。

    这里发一个vector80分代码,各位改成链前就能AC了……

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<queue>
      8 #include<stack>
      9 #include<vector>
     10 #include<cctype>
     11 using namespace std;
     12 #define enter puts("")
     13 #define space putchar(' ')
     14 #define Mem(a) memset(a, 0, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 1e6 + 5;
     21 inline ll read()
     22 {
     23     ll ans = 0;
     24     char ch = getchar(), last = ' ';
     25     while(!isdigit(ch)) {last = ch; ch = getchar();}
     26     while(isdigit(ch))
     27     {
     28         ans = ans * 10 + ch - '0'; ch = getchar();
     29     }
     30     if(last == '-') ans = -ans;
     31     return ans;
     32 }
     33 inline void write(ll x)
     34 {
     35     if(x < 0) putchar('-'), x = -x;
     36     if(x >= 10) write(x / 10);
     37     putchar(x % 10 + '0');
     38 }
     39 
     40 int n, m;
     41 
     42 struct Edge
     43 {
     44     int from, to, cap, flow;
     45 };
     46 vector<Edge> edges;
     47 vector<int> G[maxn];
     48 void addedge(int from, int to, int w)
     49 {
     50     edges.push_back((Edge){from, to, w, 0});
     51     edges.push_back((Edge){to, from, w, 0});
     52     int sz = edges.size();
     53     G[from].push_back(sz - 2);
     54     G[to].push_back(sz - 1);
     55 }
     56 
     57 int dis[maxn];
     58 bool vis[maxn];
     59 bool bfs()
     60 {
     61     for(rg int i = 1; i <= n * m; ++i) vis[i] = 0;
     62     dis[1] = 0; vis[1] = 1;
     63     queue<int> q; q.push(1);
     64     while(!q.empty())
     65     {
     66         int now = q.front(); q.pop();
     67         for(rg int i = 0; i < (int)G[now].size(); ++i)
     68         {
     69             Edge& e = edges[G[now][i]];
     70             if(!vis[e.to] && e.cap > e.flow)
     71             {
     72                 vis[e.to] = 1;
     73                 dis[e.to] = dis[now] + 1;
     74                 q.push(e.to);
     75             }
     76         }
     77     }
     78     return vis[n * m];
     79 }
     80 int cur[maxn];
     81 int dfs(const int& now, int a)
     82 {
     83     if(now == n * m || !a) return a;
     84     int flow = 0, f;
     85     for(int& i = cur[now]; i < (int)G[now].size(); ++i)
     86     {
     87         Edge& e = edges[G[now][i]];
     88         if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)
     89         {
     90             e.flow += f;
     91             edges[G[now][i] ^ 1].flow -= f;
     92             flow += f; a -= f;
     93             if(!a) break;
     94         }
     95     }
     96     return flow;
     97 }
     98 
     99 int maxflow()
    100 {
    101     int flow = 0;
    102     while(bfs())
    103     {
    104         for(rg int i = 1; i <= n * m; ++i) cur[i] = 0;
    105         flow += dfs(1, INF);
    106     }
    107     return flow;
    108 }
    109 
    110 int main()
    111 {
    112     n = read(); m = read();
    113     for(rg int i = 1; i <= n; ++i)
    114         for(rg int j = 1; j < m; ++j)
    115         {
    116             int x = read(), from = (i - 1) * m + j, to = (i - 1) * m + j + 1;
    117             addedge(from, to, x);
    118         }
    119     for(rg int i = 1; i < n; ++i)
    120         for(rg int j = 1; j <= m; ++j)
    121         {
    122             int x = read(), from = (i - 1) * m + j, to = i * m + j;
    123             addedge(from, to, x);
    124         }
    125     for(rg int i = 1; i < n; ++i)
    126         for(rg int j = 1; j < m; ++j)
    127         {
    128             int x = read(), from = (i - 1) * m + j, to = i * m + j + 1;
    129             addedge(from, to, x);
    130         }
    131     write(maxflow()); enter;
    132     return 0;
    133 }
    View Code

    然后此题据说也可以用对偶图的知识解决。

  • 相关阅读:
    图解Python 【第八篇】:网络编程-进程、线程和协程
    TCP协议三次握手、四次挥手过程
    OSI七层模型与TCP/IP五层模型
    TCP/IP协议分为哪四层,具体作用是什么。
    app测试中,ios和android的区别
    APP在用户设备发生crash,应该怎么修复
    Android四层架构
    安卓四大组件、六大布局、五大存储
    测试工程师准备找工作,需要准备什么?
    接口测试响应码解析
  • 原文地址:https://www.cnblogs.com/mrclr/p/9479589.html
Copyright © 2020-2023  润新知