【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster

表示“必须选”的模型

题目大意


题目分析

一个格子有四种方式看上去很难处理。将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点。

上图的格子里四个方向红边表示的就是一个格子的可能方向;拆点后所连蓝边的容量为1,费用即为连通两个格子的收益。

但是这样建图不能够表示某些格子必须要选。

考虑一个格子如果被选择了会发生什么:因为每个格子都处在环上,那么被选择的网格一定可以通过其他节点走到汇点。这意味着一个格子拆成的两个节点之间的边就可以先不建,而若最大流不等于网格总数,即有节点不可能被合法选中。

建图的时候一定要先理解清楚,因为有很多种错误方式,下图就是其中一个。

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cctype>
  4 #include<cstring>
  5 #include<algorithm>
  6 const int maxn = 2035;
  7 const int maxm = 100035;
  8 const int INF = 2e9;
  9
 10 struct Edge
 11 {
 12     int u,v,f,c,cst;
 13     Edge(int a=0, int b=0, int c=0, int d=0, int e=0):u(a),v(b),f(c),c(d),cst(e) {}
 14 }edges[maxm];
 15 int sne,n,m,S,T;
 16 bool ess[33][33],inq[maxn];
 17 int tagl[33][33],tagr[33][33],valc[33][33],valr[33][33];  //tagl为入点,tagr为出点
 18 int edgeTot,head[maxn],nxt[maxm],flw[maxn],cst[maxn],bck[maxn];
 19
 20 int read()
 21 {
 22     char ch = getchar();
 23     int num = 0, fl = 1;
 24     for (; !isdigit(ch); ch=getchar())
 25         if (ch==‘-‘) fl = -1;
 26     for (; isdigit(ch); ch=getchar())
 27         num = (num<<1)+(num<<3)+ch-48;
 28     return num*fl;
 29 }
 30 void addedge(int u, int v, int c, int cst)
 31 {
 32     edges[edgeTot] = Edge(u, v, 0, c,  cst), nxt[edgeTot] = head[u], head[u] = edgeTot++;
 33     edges[edgeTot] = Edge(v, u, 0, 0, -cst), nxt[edgeTot] = head[v], head[v] = edgeTot++;
 34 }
 35 void maxFlow()
 36 {
 37     int mxFlw = 0, cost = 0;
 38     for (;;)
 39     {
 40         std::queue<int> q;
 41         memset(flw, 0, sizeof flw);
 42         memset(bck, 0, sizeof bck);
 43         memset(cst, 0x3f3f3f3f, sizeof cst);
 44         q.push(S), flw[S] = INF, cst[S] = 0;
 45         for (int tmp; q.size(); )
 46         {
 47             tmp = q.front(), q.pop(), inq[tmp] = 0;
 48             for (int i=head[tmp]; i!=-1; i=nxt[i])
 49             {
 50                 int v = edges[i].v;
 51                 if (cst[tmp]+edges[i].cst < cst[v]&&edges[i].f < edges[i].c){
 52                     bck[v] = i, cst[v] = cst[tmp]+edges[i].cst;
 53                     flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
 54                     if (!inq[v]) inq[v] = 1, q.push(v);
 55                 }
 56             }
 57         }
 58         if (!flw[T]) break;
 59         for (int i=T; i!=S; i=edges[bck[i]].u)
 60             edges[bck[i]].f += flw[T], edges[bck[i]^1].f -= flw[T];
 61         mxFlw += flw[T], cost += cst[T]*flw[T];
 62     }
 63     if (mxFlw!=n*m) puts("Impossible");
 64     else printf("%d\n",-cost);
 65 }
 66 int main()
 67 {
 68     sne = read();
 69     for (int cse=1; cse<=sne; cse++)
 70     {
 71         printf("Case #%d: ",cse);
 72         memset(ess, 0, sizeof ess);
 73         memset(head, -1, sizeof head);
 74         edgeTot = 0, n = read(), m = read();
 75         for (int i=1; i<=n; i++)
 76             for (int j=1; j<m; j++)
 77                 valc[i][j] = read();
 78         for (int i=1; i<n; i++)
 79             for (int j=1; j<=m; j++)
 80                 valr[i][j] = read();
 81         for (int i=1, cnt=0; i<=n; i++)
 82             for (int j=1; j<=m; j++)
 83                 tagl[i][j] = ++cnt, tagr[i][j] = ++cnt;
 84         S = 0, T = tagr[n][m]+1;
 85         for (int i=1; i<=n; i++)
 86             for (int j=1; j<=m; j++)
 87                 if ((i+j)&1){    //为避免重复建边的处理技巧
 88                     if (j+1 <= m) addedge(tagl[i][j], tagr[i][j+1], 1, -valc[i][j]);
 89                     if (j-1 >= 1) addedge(tagl[i][j], tagr[i][j-1], 1, -valc[i][j-1]);
 90                 }else{
 91                     if (i+1 <= n) addedge(tagl[i][j], tagr[i+1][j], 1, -valr[i][j]);
 92                     if (i+1 >= 1) addedge(tagl[i][j], tagr[i-1][j], 1, -valr[i-1][j]);
 93                 }
 94         for (int i=read(); i; i--) ess[read()][read()] = 1;
 95         for (int i=1; i<=n; i++)
 96             for (int j=1; j<=m; j++)
 97             {
 98                 addedge(S, tagl[i][j], 1, 0);
 99                 addedge(tagr[i][j], T, 1, 0);
100                 if (!ess[i][j]) addedge(tagl[i][j], tagr[i][j], 1, 0);
101             }
102         maxFlow();
103     }
104     return 0;
105 } 

END

原文地址:https://www.cnblogs.com/antiquality/p/10356482.html

时间: 2024-08-30 00:05:27

【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster的相关文章

2016 China Final H - Great Cells

/************************************************************************* > File Name: H.cpp > Author: LyuCheng > Created Time: 2017-12-02 19:29 > Description: 题意:一个n×m的矩阵,填[1,k]的数,一个格子如果是所在行,列,严格最 的,那么这个格子叫做Great cell,求segma(g=0...n*m)((g+1)

2016 China Final E - Bet

/************************************************************************* > File Name: E.cpp > Author: LyuCheng > Created Time: 2017-12-02 20:38 > Description: 题意:有n各队比赛,每个队的赔率是A:B 就是说你下注x元,赢了你会得到 额外的 B/A*x的钱,问你最多买多少队,能保证哪个队赢,你都会赚钱 思路:假设每个队下注

2017 新疆赛区网络赛 J Our Journey of Dalian Ends 费用流

题目描述: Life is a journey, and the road we travel has twists and turns, which sometimes lead us to unexpected places and unexpected people. Now our journey of Dalian ends. To be carefully considered are the following questions. Next month in Xian, an e

2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流

目录 2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流 题目描述 题意(博主的鬼畜翻译): 分析: 代码 2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流 题目描述 题目描述 A coding contest will be held in this university, in a huge playground. The whole playground would be divided into N blocks, and there w

HDU 4406 GPA(网络流-最大费用流)

GPA Problem Description GPA(Grade-Point Average) is one way to measure students' academic performance in PKU. Each course has an integer credit, ranges from 1 to 99. For each course, you will get a score at the end of the semester, which is an intege

Cyclic Tour HDUOJ 费用流

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total Submission(s): 1399    Accepted Submission(s): 712 Problem Description There are N cities in our country, and M one-way roads connecting them. Now Li

HDU 3395 Special Fish(最大费用流)

Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1814    Accepted Submission(s): 678 Problem Description There is a kind of special fish in the East Lake where is closed to campus o

POJ 3422 kaka&#39;s matrix trvals(费用流)

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <cma

hdu 2448 Mining Station on the Sea【网络费用流】

Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2371    Accepted Submission(s): 732 Problem Description The ocean is a treasure house of resources and the development