【题意】

对每个格子确定上下取整,使得满足1.A[n][n]=0 2.每行列前n-1个之和为第n个 3.格子之和尽量大。

【思路】

设格子(i,j)上下取整分别为up(i,j)down(i,j),构图如下:

  1. S,Xi,[ down(i,n),up(i,n) ] ,i<n
  2. Yi,T,[ down(n,i),up(n,i) ] ,i<n
  3. Xi,Yj,[down(i,j),up(i,j) ] , i<n ,j<n

于是问题转化成了有源汇的上下界最大流问题。

【代码】

  1. #include<set>
  2. #include<cmath>
  3. #include<queue>
  4. #include<vector>
  5. #include<cstdio>
  6. #include<cstring>
  7. #include<iostream>
  8. #include<algorithm>
  9. #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
  10. #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
  11. using namespace std;
  12.  
  13. typedef long long ll;
  14. const int N = 4e2+;
  15. const int inf = 1e9;
  16.  
  17. ll read() {
  18. char c=getchar();
  19. ll f=,x=;
  20. while(!isdigit(c)) {
  21. if(c=='-') f=-; c=getchar();
  22. }
  23. while(isdigit(c))
  24. x=x*+c-'',c=getchar();
  25. return x*f;
  26. }
  27.  
  28. struct Edge {
  29. int u,v,cap,flow;
  30. Edge(int u=,int v=,int cap=,int flow=)
  31. :u(u),v(v),cap(cap),flow(flow){}
  32. };
  33. struct Dinic {
  34. int n,m,s,t;
  35. int d[N],cur[N],vis[N];
  36. vector<int> g[N];
  37. vector<Edge> es;
  38. queue<int> q;
  39. void init(int n) {
  40. this->n=n;
  41. es.clear();
  42. FOR(i,,n) g[i].clear();
  43. }
  44. void clear() {
  45. FOR(i,,(int)es.size()-) es[i].flow=;
  46. }
  47. void AddEdge(int u,int v,int w) {
  48. es.push_back(Edge(u,v,w,));
  49. es.push_back(Edge(v,u,,));
  50. m=es.size();
  51. g[u].push_back(m-);
  52. g[v].push_back(m-);
  53. }
  54. int bfs() {
  55. memset(vis,,sizeof(vis));
  56. q.push(s); d[s]=; vis[s]=;
  57. while(!q.empty()) {
  58. int u=q.front(); q.pop();
  59. FOR(i,,(int)g[u].size()-) {
  60. Edge& e=es[g[u][i]];
  61. int v=e.v;
  62. if(!vis[v]&&e.cap>e.flow) {
  63. vis[v]=;
  64. d[v]=d[u]+;
  65. q.push(v);
  66. }
  67. }
  68. }
  69. return vis[t];
  70. }
  71. int dfs(int u,int a) {
  72. if(u==t||!a) return a;
  73. int flow=,f;
  74. for(int& i=cur[u];i<g[u].size();i++) {
  75. Edge& e=es[g[u][i]];
  76. int v=e.v;
  77. if(d[v]==d[u]+&&(f=dfs(v,min(a,e.cap-e.flow)))>) {
  78. e.flow+=f;
  79. es[g[u][i]^].flow-=f;
  80. flow+=f; a-=f;
  81. if(!a) break;
  82. }
  83. }
  84. return flow;
  85. }
  86. int MaxFlow(int s,int t) {
  87. this->s=s,this->t=t;
  88. int flow=;
  89. while(bfs()) {
  90. memset(cur,,sizeof(cur));
  91. flow+=dfs(s,inf);
  92. }
  93. return flow;
  94. }
  95. } dc;
  96.  
  97. int n,in[N];
  98. double a[N][N];
  99.  
  100. int main()
  101. {
  102. n=read();
  103. FOR(i,,n) FOR(j,,n) scanf("%lf",&a[i][j]);
  104. int s=,t=n+n+,S=t+,T=S+;
  105. dc.init(T+);
  106. FOR(i,,n-) {
  107. if(a[i][n]!=(int)a[i][n]) dc.AddEdge(s,i,);
  108. in[s]-=(int)a[i][n],in[i]+=(int)a[i][n];
  109. }
  110. FOR(i,,n-) {
  111. if(a[n][i]!=(int)a[n][i]) dc.AddEdge(i+n,t,);
  112. in[i+n]-=(int)a[n][i],in[t]+=(int)a[n][i];
  113. }
  114. FOR(i,,n-) FOR(j,,n-) {
  115. if(a[i][j]!=(int)a[i][j]) dc.AddEdge(i,j+n,);
  116. in[i]-=(int)a[i][j],in[j+n]+=(int)a[i][j];
  117. }
  118. int sum=;
  119. FOR(i,s,t) {
  120. if(in[i]>) dc.AddEdge(S,i,in[i]),sum+=in[i];
  121. if(in[i]<) dc.AddEdge(i,T,-in[i]);
  122. }
  123. dc.AddEdge(t,s,inf);
  124. if(sum!=dc.MaxFlow(S,T)) puts("No");
  125. else
  126. printf("%d\n",*dc.MaxFlow(s,t));
  127. return ;
  128. }

bzoj 3698 XWW的难题(有源汇的上下界最大流)的更多相关文章

  1. BZOJ 3698: XWW的难题 [有源汇上下界最大流]

    3698: XWW的难题 题意:(1)A[N][N]=0:(2)矩阵中每行的最后一个元素等于该行前N-1个数的和:(3)矩阵中每列的最后一个元素等于该列前N-1个数的和.给A中的数进行取整操作(可以是 ...

  2. BZOJ.3698.XWW的难题(有源汇上下界最大流ISAP)

    题目链接 按套路行列作为两部分,连边 \(S->row->column->T\). S向代表行的元素连边cap(A[i][n])(容量上下界为上下取整),代表列的元素向T连边cap( ...

  3. bzoj 2502 清理雪道(有源汇的上下界最小流)

    [题意] 有一个DAG,要求每条边必须经过一次,求最少经过次数. [思路] 有上下界的最小流.  边的下界为1,上界为无穷.构造可行流模型,先不加ts边跑一遍最大流,然后加上t->s的inf边跑 ...

  4. LOJ116 - 有源汇有上下界最大流

    原题链接 Description 模板题啦~ Code //有源汇有上下界最大流 #include <cstdio> #include <cstring> #include & ...

  5. 【Loj116】有源汇有上下界最大流(网络流)

    [Loj116]有源汇有上下界最大流(网络流) 题面 Loj 题解 模板题. #include<iostream> #include<cstdio> #include<c ...

  6. loj #116. 有源汇有上下界最大流

    题目链接 有源汇有上下界最大流,->上下界网络流 注意细节,重置cur和dis数组时,有n+2个点 #include<cstdio> #include<algorithm> ...

  7. loj #117. 有源汇有上下界最小流

    题目链接 有源汇有上下界最小流,->上下界网络流 注意细节,边数组也要算上后加到SS,TT边. #include<cstdio> #include<algorithm> ...

  8. LOJ.117.[模板]有源汇有上下界最小流(Dinic)

    题目链接 有源汇有上下界最小流 Sol1. 首先和无源汇网络流一样建图,求SS->TT最大流: 然后连边(T->S,[0,INF]),再求一遍SS->TT最大流,答案为新添加边的流量 ...

  9. [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流

    poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...

  10. 【LOJ116】有源汇有上下界最大流(模板题)

    点此看题面 大致题意: 给你每条边的流量上下界,让你先判断是否存在可行流.若存在,则输出最大流. 无源汇上下界可行流 在做此题之前,最好先去看看这道题目:[LOJ115]无源汇有上下界可行流. 大致思 ...

随机推荐

  1. Orcle数据库编程:一

    1.PL/SQL是一种块结构的语言,一个PL/SQL程序包含了一个或者多个逻辑块,逻辑块中可以声明变量,变量在使用之前必须先声明. declare mstu student%ROWTYPE;--定义参 ...

  2. linux 查看某一端口的占用情况

    查看某一端口的占用情况: lsof -i:端口号,例如查看端口21是否被占用 lsof -i: 实例:查看端口是否被占用,如果被占用结束掉该端口 [root@localhost splunk]# ls ...

  3. 转 Android的消息处理机制(图+源码分析)——Looper,Handler,Message

    作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种 ...

  4. 【Linux常用工具】03. Linux性能测试工具ab

    在Apache服务器的套件中,有一个叫做 ab (ApacheBench) 的工具. ApacheBench 主要是用来测试Apache服务器执行效率用的 ApacheBench 可以针对某个特定的 ...

  5. bat拷贝文件

    最近在部署服务器的时候,需要用到把一个站点文件拷贝到其他站点.一个一个手动copy太累人了,写了个简单的批处理文件,基本能达到目的,具体怎么做呢: 1.把需要拷贝到各个站点的文件,单独放到一个目录下. ...

  6. poj 2828 Buy Tickets (线段树)

    题目:http://poj.org/problem?id=2828 题意:有n个人插队,给定插队的先后顺序和插在哪个位置还有每个人的val,求插队结束后队伍各位置的val. 线段树里比较简单的题目了, ...

  7. struct TABLE_SHARE

    struct TABLE_SHARE { TABLE_SHARE() {} /* Remove gcc warning */ /** Category of this table. */ TABLE_ ...

  8. UVa 1636 (概率) Headshot

    既然是第一道概率题,就正儿八经地分析一下吧. 题意: 有一个左轮枪,里面随机装了或者没装子弹,用一个01序列表示.现在已知扣动第一次扳机没有子弹,问是继续扣动扳机还是随机转动一下再扣,那种选择使得第二 ...

  9. sql2005主从数据库同步配置

    网站规模到了一定程度之后,该分的也分了,该优化的也做了优化,但是还是不能满足业务上对性能的要求:这时候我们可以考虑使用主从库.主从库是两台服务器上的两个数据库,主库以最快的速度做增删改操作+最新数据的 ...

  10. wdcp系统升级mysql5.7.11

    1.下载解压 下载地址为:http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.12-linux-glibc2.5-x86_64.tar.gz ...