bzoj3698 XWW的难题

题意:给你个n * n的实数矩阵,你需要把它中的每个数上/下取整,并满足如下条件:

每行最后一个数等于前面的和。

每列最后一个数等于前面的和。

n行n列的那个元素始终为0,不予考虑。

求满足条件下矩阵中元素的最大总和是多少。

解:

首先假设全部下取整。

s->行->列->t连边,可以发现每条边都有上下界。

有源汇有上下界最大流。

出来的最大流*3就是答案。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <queue>
  4 #include <cstring>
  5
  6 const int N = 210, M = 1000010, INF = 0x3f3f3f3f;
  7
  8 struct Edge {
  9     int nex, v, c;
 10 }edge[M << 1]; int top = 1;
 11
 12 int e[N], d[N], ot[N];
 13 std::queue<int> Q;
 14
 15 inline void add(int x, int y, int z) {
 16     top++;
 17     edge[top].v = y;
 18     edge[top].c = z;
 19     edge[top].nex = e[x];
 20     e[x] = top;
 21
 22     top++;
 23     edge[top].v = x;
 24     edge[top].c = 0;
 25     edge[top].nex = e[y];
 26     e[y] = top;
 27     return;
 28 }
 29
 30 inline bool BFS(int s, int t) {
 31     memset(d, 0, sizeof(d));
 32     d[s] = 1;
 33     Q.push(s);
 34     while(!Q.empty()) {
 35         int x = Q.front();
 36         Q.pop();
 37         for(int i = e[x]; i; i = edge[i].nex) {
 38             int y = edge[i].v;
 39             if(!edge[i].c || d[y]) {
 40                 continue;
 41             }
 42             d[y] = d[x] + 1;
 43             Q.push(y);
 44         }
 45     }
 46     return d[t];
 47 }
 48
 49 int DFS(int x, int t, int maxF) {
 50     if(x == t) {
 51         return maxF;
 52     }
 53     int ans = 0;
 54     for(int i = e[x]; i; i = edge[i].nex) {
 55         int y = edge[i].v;
 56         if(!edge[i].c || d[x] + 1 != d[y]) {
 57             continue;
 58         }
 59         int temp = DFS(y, t, std::min(edge[i].c, maxF - ans));
 60         if(!temp) {
 61             d[y] = INF;
 62         }
 63         ans += temp;
 64         edge[i].c -= temp;
 65         edge[i ^ 1].c += temp;
 66         if(ans == maxF) {
 67             break;
 68         }
 69     }
 70     return ans;
 71 }
 72
 73 inline int solve(int s, int t) {
 74     int ans = 0;
 75     while(BFS(s, t)) {
 76         ans += DFS(s, t, INF);
 77     }
 78     return ans;
 79 }
 80
 81 int main() {
 82     int n;
 83     scanf("%d", &n);
 84     int s = n * 2 + 1, t = n * 2 + 2, ss = n * 2 + 3, tt = n * 2 + 4;
 85     for(int i = 1; i <= n; i++) {
 86         for(int j = 1; j <= n; j++) {
 87             double y;
 88             scanf("%lf", &y);
 89             int x = (int)(y);
 90             if(i < n && j < n) {
 91                 // add (i, n + j, x)
 92                 ot[i] += x;
 93                 ot[n + j] -= x;
 94             }
 95             else if(i < n) {
 96                 // add (s, i, x)
 97                 ot[s] += x;
 98                 ot[i] -= x;
 99             }
100             else if(j < n) {
101                 // add(n + j, t, x)
102                 ot[n + j] += x;
103                 ot[t] -= x;
104             }
105             if(x < y) {
106                 if(i < n && j < n) {
107                     add(i, n + j, 1);
108                 }
109                 else if(i < n) {
110                     add(s, i, 1);
111                 }
112                 else if(j < n) {
113                     add(n + j, t, 1);
114                 }
115             }
116         }
117     }
118     int sum = 0;
119     for(int i = 1; i <= t; i++) {
120         if(ot[i] > 0) {
121             add(i, tt, ot[i]);
122         }
123         else if(ot[i] < 0) {
124             add(ss, i, -ot[i]);
125             sum -= ot[i];
126         }
127     }
128     add(t, s, INF);
129
130     int ans = solve(ss, tt);
131     if(ans != sum) {
132         puts("No");
133         return 0;
134     }
135
136     for(int i = e[ss]; i; i = edge[i].nex) {
137         edge[i].c = edge[i ^ 1].c = 0;
138     }
139     for(int i = e[tt]; i; i = edge[i].nex) {
140         edge[i].c = edge[i ^ 1].c = 0;
141     }
142     //edge[top].c = edge[top - 1].c = 0;
143
144     ans = solve(s, t);
145     //printf("ans + cost %d + %d \n", ans * 3, cost);
146     printf("%d", ans * 3);
147
148     return 0;
149 }

AC代码

原文地址:https://www.cnblogs.com/huyufeifei/p/10104259.html

时间: 2024-08-30 11:33:32

bzoj3698 XWW的难题的相关文章

[BZOJ3698] XWW的难题 网络流

3698: XWW的难题 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 533  Solved: 275[Submit][Status][Discuss] Description XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核.XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XWW性.称一个N*N的矩阵满足XWW性当且仅当:(1)A[N][N]=0

[BZOJ3698]XWW的难题解题报告|上下界网络流|有源汇最大流

XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核.XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XWW性.称一个N*N的矩阵满足XWW性当且仅当:(1)A[N][N]=0:(2)矩阵中每行的最后一个元素等于该行前N-1个数的和:(3)矩阵中每列的最后一个元素等于该列前N-1个数的和.现在你要给A中的数进行取整操作(可以是上取整或者下取整),使得最后的A矩阵仍然满足XWW性.同时XWW还要求A中的元

【BZOJ3698】XWW的难题 有上下界的最大流

[BZOJ3698]XWW的难题 Description XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核.XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XWW性.称一个N*N的矩阵满足XWW性当且仅当:(1)A[N][N]=0:(2)矩阵中每行的最后一个元素等于该行前N-1个数的和:(3)矩阵中每列的最后一个元素等于该列前N-1个数的和.现在你要给A中的数进行取整操作(可以是上取整或者下取整),

【bzoj3698】XWW的难题 有上下界最大流

题目描述 XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核.XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XWW性.称一个N*N的矩阵满足XWW性当且仅当:(1)A[N][N]=0:(2)矩阵中每行的最后一个元素等于该行前N-1个数的和:(3)矩阵中每列的最后一个元素等于该列前N-1个数的和.现在你要给A中的数进行取整操作(可以是上取整或者下取整),使得最后的A矩阵仍然满足XWW性.同时XWW还要

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

有上下界网络流

bzoj3876:支线剧情 [模型]有源无汇 [题意]每个点至少到达一次,令经过的总边权最小,每次从1出发. [构图]对于x-->y 流量下界为1,上界为inf,费用为w 然后直接从S到T跑一遍费用流.注意图中的1代表了下界. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 202020 5 #define inf 1000000000 6 using namespa

1225 八数码难题

1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765

“黑五”的本土化难题,如何定位、立足?

黑五,或者黑色星期五,对大部分中国人来说都会觉得很陌生,但这个在欧美如同双十一的购物节日已经开始被一部分中国消费者所接受并且积极的进行消费购物.虽然在国内黑五还无法与双十一相提并论,但随着跨境电商的兴起,黑五的本土化氛围正越来越浓. "黑五"关注度持续升温 从特定人群向多元化.年轻化转变 从市场层面的变化来看,这两年跨境电商的持续发展为黑五提供了基本的市场促销环境,虽然国内的黑五发展程度尚不足以与双十一相提并论,但对跨境电商企业而言,这几年已经逐渐向市场传达到了"黑五&quo

hdu 1251 统计难题(字典树)

Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提