zoukankan      html  css  js  c++  java
  • UVa 1515 (最小割) Pool construction

    题意:

    输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b。

    但要保证最外一圈是草,求最小费用。

    分析:

    还不是特别理解紫书上的讲解。。

    首先把最外一圈的洞变成草,并累加花费。

    增加一个源点和一个汇点,源点连接每个草地,汇点连接每个洞。

    源点与最外一圈的草地连一条容量无穷大的边,与其他草地连一条容量为d的边。表示把这条弧切断,割的容量增加d,草就会变成洞。

    每个洞与汇点连一条容量为f的边。

    相邻两个格子之间连一条双向边。

    用最大流算法求最小割在加上之前把边界上的洞变成草的费用,就是最小花费。

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 const int maxn = 50 * 50 + 10;
      6 const int INF = 1000000000;
      7 
      8 struct Edge
      9 {
     10     int from, to, cap, flow;
     11 };
     12 
     13 bool operator < (const Edge& a, const Edge& b)
     14 { return a.from < b.from || ( a.from == b.from && a.to < b.to ); }
     15 
     16 struct Dinic
     17 {
     18     int n, m, s, t;
     19     vector<Edge> edges;
     20     vector<int> G[maxn];
     21     bool vis[maxn];    //BFS
     22     int d[maxn];    //起点到i的距离
     23     int cur[maxn];    //当前弧指针
     24 
     25     int Init(int n)
     26     {
     27         for(int i = 0; i < n; ++i) G[i].clear();
     28         edges.clear();
     29     }
     30 
     31     void AddEdge(int from, int to, int cap)
     32     {
     33         edges.push_back(Edge{from, to, cap, 0});
     34         edges.push_back(Edge{to, from, 0, 0});
     35         m = edges.size();
     36         G[from].push_back(m-2);
     37         G[to].push_back(m-1);
     38     }
     39 
     40     bool BFS()
     41     {
     42         memset(vis, false, sizeof(vis));
     43         queue<int> Q;
     44         Q.push(s);
     45         vis[s] = true;
     46         d[s] = 0;
     47         while(!Q.empty())
     48         {
     49             int x = Q.front(); Q.pop();
     50             for(int i = 0; i < G[x].size(); ++i)
     51             {
     52                 Edge& e = edges[G[x][i]];
     53                 if(!vis[e.to] && e.cap > e.flow)
     54                 {
     55                     vis[e.to] = true;
     56                     d[e.to] = d[x] + 1;
     57                     Q.push(e.to);
     58                 }
     59             }
     60         }
     61         return vis[t];
     62     }
     63 
     64     int DFS(int x, int a)
     65     {
     66         if(x == t || a == 0) return a;
     67         int flow = 0, f;
     68         for(int& i = cur[x]; i < G[x].size(); ++i)
     69         {
     70             Edge& e = edges[G[x][i]];
     71             if(d[x] + 1 ==d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0)
     72             {
     73                 e.flow += f;
     74                 edges[G[x][i]^1].flow -= f;
     75                 flow += f;
     76                 a -= f;
     77                 if(a == 0) break;
     78             }
     79         }
     80         return flow;
     81     }
     82 
     83     int MaxFlow(int s, int t)
     84     {
     85         this->s = s; this->t = t;
     86         int flow = 0;
     87         while(BFS())
     88         {
     89             memset(cur, 0, sizeof(cur));
     90             flow += DFS(s, INF);
     91         }
     92         return flow;
     93     }
     94 }g;
     95 
     96 int w, h;
     97 char pool[99][99];
     98 
     99 inline int ID(int i, int j) { return i*w+j; }
    100 
    101 int main()
    102 {
    103     //freopen("in.txt", "r", stdin);
    104 
    105     int T, d, f, b;
    106     scanf("%d", &T);
    107     while(T--)
    108     {
    109         scanf("%d%d%d%d%d", &w, &h, &d, &f, &b);
    110         for(int i = 0; i < h; ++i) scanf("%s", pool[i]);
    111         int cost = 0;
    112         for(int i = 0; i < h; ++i)//把边上的洞填成草
    113         {
    114             if(pool[i][0] == '.') { pool[i][0] = '#'; cost += f; }
    115             if(pool[i][w-1] == '.') { pool[i][w-1] = '#'; cost += f; }
    116         }
    117         for(int i = 0; i < w; ++i)
    118         {
    119             if(pool[0][i] == '.') { pool[0][i] = '#'; cost += f; }
    120             if(pool[h-1][i] == '.') { pool[h-1][i] = '#'; cost += f; }
    121         }
    122 
    123         g.Init(h*w+2);
    124         for(int i = 0; i < h; i++)
    125             for(int j = 0; j < w; j++)
    126             {
    127                 if(pool[i][j] == '#')
    128                 {
    129                     int cap = d;
    130                     if(i == 0 || i == h-1 || j == 0 || j == w-1) cap = INF;
    131                     g.AddEdge(w*h, ID(i, j), cap);
    132                 }
    133                 else
    134                 {
    135                     g.AddEdge(ID(i, j), w*h+1, f);
    136                 }
    137                 if(i > 0) g.AddEdge(ID(i, j), ID(i-1, j), b);
    138                 if(i < h-1) g.AddEdge(ID(i, j), ID(i+1, j), b);
    139                 if(j > 0) g.AddEdge(ID(i, j), ID(i, j-1), b);
    140                 if(j < w-1) g.AddEdge(ID(i, j), ID(i, j+1), b);
    141             }
    142 
    143         printf("%d
    ", cost + g.MaxFlow(w*h, w*h+1));
    144     }
    145 
    146     return 0;
    147 }
    代码君
  • 相关阅读:
    使用 MDT 2010 进行可伸缩部署
    Windows Phone 7 WebBrowser 中文乱码问题
    如何安装Windows Phone SDK 7.1 Release Candidate (RC)
    Windows Phone应用 博客园阅读器
    将WindowsPhoneApp部署到HTC Surround,兄弟们支个招如何进行Debug
    私有代码存放仓库 BitBucket
    入门:添加一个支持获取单一资源以及支持POST,PUT和DELETE方法
    Html5 学习利器 Web Standards Update for Microsoft Visual Studio 2010 SP1
    在启用了IPV6的机器上获取客户端ipv4地址
    EMA算法的C#实现
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4294964.html
Copyright © 2011-2022 走看看