$ \color{#0066ff}{ 题目描述 }$

小E在好友小W的家中发现一幅神奇的图画,对此颇有兴趣。它可以被看做一个包含N×M个像素的黑白图像,为了方便起见,我们用0表示白色像素,1表示黑色像素。小E认为这幅图画暗藏玄机,因此他记录下了这幅图像中每行、每列的黑色像素数量,以回去慢慢研究其中的奥妙。

有一天,小W不慎将图画打湿,原本的图像已经很难分辨。他十分着急,于是找来小E,希望共同还原这幅图画。根据打湿后的图画,他们无法确定真正的图像,然而可以推测出每个像素原本是黑色像素的概率Pij%。那么,一个完整的图像的出现概率就可以定义为:

其中Sij表示在还原后的图像中,像素是白色(0)还是黑色(1)。换句话说,一个完整图像出现概率就等于其所有黑色像素的出现概率之积。显然,图像的黑色像素不能包含概率为0的像素。

然而,小E对此也无能为力。因此他们找到了会编程的小F,也就是你,请你根据以上信息,告诉他们最有可能是原始图像的答案是什么。

\(\color{#0066ff}{输入格式}\)

输入文件image.in的第一行是两个正整数N和M,表示图像大小。

接下来N行每行包含M个整数,表示每个像素是黑色像素的概率为Pij%。0 ≤ Pij < 100。

接下来一行有N个非负整数,表示每一行中黑色像素的个数。

接下来一行有M个非负整数,表示每一列中黑色像素的个数。

\(\color{#0066ff}{输出格式}\)

输出文件image.out包含一个N×M的01矩阵,表示你还原出的图像。输出不包含空格。图像每行、每列中1的个数必须与输入一致,且是所有可能的图像中出现概率最大的一个。输入数据保证至少存在一个可能的图像。如果有多种最优图像,任意输出一种即可。

\(\color{#0066ff}{输入样例}\)

  1. 2 2
  2. 90 10
  3. 20 80
  4. 1 1
  5. 1 1

\(\color{#0066ff}{输出样例}\)

  1. 10
  2. 01

\(\color{#0066ff}{数据范围与提示}\)

样例解释:共有两种可能的图像:

01 10 和 10 01 前者的出现概率是0.1×0.2=0.02,后者的出现概率是0.9×0.8=0.72,故后者是最优图像。

对于20%的数据,N , M ≤ 5;

对于100%的数据,N , M ≤ 100。

\(\color{#0066ff}{题解}\)

一看数据范围,显然的费用流啦

但是注意这里是一个\(\prod\)

于是我们把边权变为概率

反向边稍微改变一下,就是它分之一,这样就满足了

然而。。。这题居然卡EK

于是得写ZKW费用流才能过qwq

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define LL long long
  4. LL in() {
  5. char ch; LL x = 0, f = 1;
  6. while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
  7. for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
  8. return x * f;
  9. }
  10. const int inf = 0x7fffffff;
  11. const int maxn = 5050;
  12. struct node {
  13. int to, can;
  14. double dis;
  15. node *nxt, *rev;
  16. node(int to = 0, int can = 0, double dis = 0, node *nxt = NULL): to(to), can(can), dis(dis), nxt(nxt) {
  17. rev = NULL;
  18. }
  19. };
  20. std::deque<int> q;
  21. node *head[maxn], *cur[maxn];
  22. double dis[maxn];
  23. const double eps = 1e-6;
  24. bool choose[120][120];
  25. bool vis[maxn];
  26. int n, m, s, t;
  27. LL ans;
  28. void add(int from, int to, double dis, int can) {
  29. head[from] = new node(to, can, dis, head[from]);
  30. }
  31. void link(int from, int to, double dis, int can) {
  32. add(from, to, dis, can);
  33. add(to, from, 1.0 / dis, 0);
  34. head[from]->rev = head[to];
  35. head[to]->rev = head[from];
  36. }
  37. bool spfa() {
  38. for(int i = s; i <= t; i++) dis[i] = -1, vis[i] = false, cur[i] = head[i];
  39. q.push_front(s);
  40. dis[s] = 1.0;
  41. while(!q.empty()) {
  42. int tp = q.front(); q.pop_front();
  43. vis[tp] = false;
  44. for(node *i = head[tp]; i; i = i->nxt)
  45. if(dis[i->to] < dis[tp] * i->dis && i->can) {
  46. dis[i->to] = dis[tp] * i->dis;
  47. if(!vis[i->to]) {
  48. if(!q.empty() && dis[i->to] < dis[q.front()]) q.push_back(i->to);
  49. else q.push_front(i->to);
  50. vis[i->to] = true;
  51. }
  52. }
  53. }
  54. return dis[t] > 0;
  55. }
  56. int dfs(int x, int change) {
  57. if(x == t || !change) return change;
  58. int flow = 0, ls;
  59. vis[x] = true;
  60. for(node *i = cur[x]; i; i = i->nxt) {
  61. cur[x] = i;
  62. if(!vis[i->to] && fabs(dis[i->to] - (dis[x] * i->dis)) <= eps && (ls = dfs(i->to, std::min(i->can, change)))) {
  63. flow += ls;
  64. change -= ls;
  65. i->can -= ls;
  66. i->rev->can += ls;
  67. if(!change) break;
  68. }
  69. }
  70. vis[x] = false;
  71. return flow;
  72. }
  73. void zkw() {
  74. while(spfa()) dfs(s, inf);
  75. for(int i = 1; i <= n; i++)
  76. for(node *o = head[i]; o; o = o->nxt) {
  77. if(o->to == s) continue;
  78. if(!o->can) choose[i][o->to - n] = true;
  79. }
  80. for(int i = 1; i <= n; i++) {
  81. for(int j = 1; j <= m; j++) printf("%d", choose[i][j]);
  82. puts("");
  83. }
  84. }
  85. int main() {
  86. n = in(), m = in(), s = 0, t = n + m + 1;
  87. for(int i = 1; i <= n; i++)
  88. for(int j = 1; j <= m; j++) {
  89. int x = in();
  90. if(x) link(i, n + j, x * 0.01, 1);
  91. }
  92. for(int i = 1; i <= n; i++) link(s, i, 1.0, in());
  93. for(int i = 1; i <= m; i++) link(n + i, t, 1.0, in());
  94. zkw();
  95. return 0;
  96. }

P2410 [SDOI2009]最优图像 ZKW最大费用最大流的更多相关文章

  1. 【学术篇】SDOI2009 最优图像

    又是一道辣鸡卡常数题…. luogu上有些题的时限还是有毒的… 最后也只能靠O2过掉了… 不过给我原题当时的2s我随便过给你看嘛, 哪怕评测姬慢50%都没关系的.. 贴一下codevs的截图… 你看最 ...

  2. poj 2195 二分图最优匹配 或 最小费用最大流

    就是最基本的二分图最优匹配,将每个人向每个房子建一条边,权值就是他们manhattan距离.然后对所有权值取反,求一次最大二分图最优匹配,在将结果取反就行了. #include<iostream ...

  3. LOJ#3097 [SNOI2019]通信 最小费用最大流+cdq分治/主席树/分块优化建图

    瞎扯 我们网络流模拟赛(其实是数据结构模拟赛)的T2. 考场上写主席树写自闭了,直接交了\(80pts\)的暴力,考完出来突然发现: woc这个题一个cdq几行就搞定了! 题意简述 有\(n\)个哨站 ...

  4. 最小费用最大流——ZKW

    对于最小费用最大流,我们的通常做法是EK+SPFA. 然而,卡常界大佬ZKW发明了一个求解最小费用最大流的方法,很强啊. 在学ZKW费用流前,先说说KM算法. KM算法 为啥要先提这个呢?因为ZKW费 ...

  5. [SDOI2009]晨跑[最小费用最大流]

    [SDOI2009]晨跑 最小费用最大流的板子题吧 令 \(i'=i+n\) \(i -> i'\) 建一条流量为1费用为0的边这样就不会对答案有贡献 其次是对 \(m\) 条边建 \(u'-& ...

  6. bzoj 1877 [SDOI2009]晨跑(最小费用最大流)

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...

  7. BZOJ 1877:[SDOI2009]晨跑(最小费用最大流)

    晨跑DescriptionElaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个 ...

  8. BZOJ-1061 志愿者招募 线性规划转最小费用最大流+数学模型 建模

    本来一眼建模,以为傻逼题,然后发现自己傻逼...根本没想到神奇的数学模型..... 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 ...

  9. bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1576  Solved: 954[Submit][Statu ...

随机推荐

  1. 摄影之HDR

    摄影之HDR 高动态范围图像(High-Dynamic Range,简称HDR),相比普通的图像,可以提供更多的动态范围和图像细节,根据不同的曝光时间的LDR(Low-Dynamic Range)图像 ...

  2. In function 'int av_clipl_int32_c(int64_t)': error: 'UINT64_C' was not declared in this scope

    cygwin下使用ndk编译jni时遇到的错误: /ffmpeg/include/libavutil/common.h: In function 'int av_clipl_int32_c(int64 ...

  3. jenkins 学习记录2

    主题 在之前的学习中(http://www.cnblogs.com/abcwt112/p/6274575.html)我已经学会怎么打包了..这篇文章记录分享我学习如何利用jenkins将打完的包发布到 ...

  4. 解决Maximum execution time of 120 seconds exceeded

    在循环开始前加入代码: //设置超时时间 ini_set("max_execution_time",18000); set_time_limit(0); set_time_limi ...

  5. Leetcode:Regular Expression Matching分析和实现

    题目大意是要求我们实现一个简单的正则表达式全匹配判断.其中正则表达式中只包含一般字符,以及全匹配字符.和变长字符*.其中.可以匹配一个字符,而*与前一个字符相关联,x*可以被看作任意多个x(0到正无穷 ...

  6. Docker 学习笔记_安装和使用MongoDB

    一.准备 1.宿主机OS:Win10 64 2.虚拟机OS:Ubuntu18.04 3.账号:docker 二.安装 1.搜索MongoDB镜像                            ...

  7. win10手动开启wifi

    win+R键,输入cmd,以管理员身份运行,输入netsh wlan set hostednetwork mode=allow ssid=wifi key=wifimima123回车 解释一下: ss ...

  8. SpringMVC——处理 JSON:使用 HttpMessageConverter

    一.SpringMVC处理JSON流程 1. 加入 jar 包: jackson-annotations-2.1.5.jarjackson-core-2.1.5.jarjackson-databind ...

  9. CORS同源策略

    同源策略以及跨域资源共享在大部分情况下针对的是Ajax请求.同源策略主要限制了通过XMLHttpRequest实现的Ajax请求,如果请求的是一个“异源”地址,浏览器将不允许读取返回的内容. 支持同源 ...

  10. Customizing Site-Wide Behavior for ASP.NET Web Pages (Razor) Sites

    Customizing Site-Wide Behavior for ASP.NET Web Pages (Razor) Sites By Tom FitzMacken|February 17, 20 ...