BZOJ 2597 剪刀石头布(最小费用最大流)(WC2007)
Description
Input
Output
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 8 const int MAXN = 110; 9 const int MAXV = MAXN * MAXN; 10 const int MAXE = MAXN * MAXV; 11 const int INF = 0x7f7f7f7f; 12 13 struct ZWK_FLOW { 14 int head[MAXV], dis[MAXV]; 15 int to[MAXE], next[MAXE], flow[MAXE], cost[MAXE]; 16 int n, ecnt, st, ed; 17 18 void init() { 19 memset(head, 0, sizeof(head)); 20 ecnt = 2; 21 } 22 23 void add_edge(int u, int v, int c, int w) { 24 to[ecnt] = v; flow[ecnt] = c; cost[ecnt] = w; next[ecnt] = head[u]; head[u] = ecnt++; 25 to[ecnt] = u; flow[ecnt] = 0; cost[ecnt] = -w; next[ecnt] = head[v]; head[v] = ecnt++; 26 //printf("%d %d %d %d\n", u, v, c, w); 27 } 28 29 void spfa() { 30 for(int i = 1; i <= n; ++i) dis[i] = INF; 31 priority_queue<pair<int, int> > que; 32 dis[st] = 0; que.push(make_pair(0, st)); 33 while(!que.empty()) { 34 int u = que.top().second, d = -que.top().first; que.pop(); 35 if(d != dis[u]) continue; 36 for(int p = head[u]; p; p = next[p]) { 37 int &v = to[p]; 38 if(flow[p] && dis[v] > d + cost[p]) { 39 dis[v] = d + cost[p]; 40 que.push(make_pair(-dis[v], v)); 41 } 42 } 43 } 44 int t = dis[ed]; 45 for(int i = 1; i <= n; ++i) dis[i] = t - dis[i]; 46 } 47 48 int minCost, maxFlow; 49 bool vis[MAXV]; 50 51 int add_flow(int u, int aug) { 52 if(u == ed) { 53 maxFlow += aug; 54 minCost += dis[st] * aug; 55 return aug; 56 } 57 vis[u] = true; 58 int now = aug; 59 for(int p = head[u]; p; p = next[p]) { 60 int &v = to[p]; 61 if(flow[p] && !vis[v] && dis[u] == dis[v] + cost[p]) { 62 int t = add_flow(v, min(now, flow[p])); 63 flow[p] -= t; 64 flow[p ^ 1] += t; 65 now -= t; 66 if(!now) break; 67 } 68 } 69 return aug - now; 70 } 71 72 bool modify_label() { 73 int d = INF; 74 for(int u = 1; u <= n; ++u) if(vis[u]) { 75 for(int p = head[u]; p; p = next[p]) { 76 int &v = to[p]; 77 if(flow[p] && !vis[v]) d = min(d, dis[v] + cost[p] - dis[u]); 78 } 79 } 80 if(d == INF) return false; 81 for(int i = 1; i <= n; ++i) if(vis[i]) dis[i] += d; 82 return true; 83 } 84 85 int min_cost_flow(int ss, int tt, int nn) { 86 st = ss, ed = tt, n = nn; 87 minCost = maxFlow = 0; 88 spfa(); 89 while(true) { 90 while(true) { 91 for(int i = 1; i <= n; ++i) vis[i] = false; 92 if(!add_flow(st, INF)) break; 93 } 94 if(!modify_label()) break; 95 } 96 return minCost; 97 } 98 } G; 99 100 int n, m; 101 int mat[MAXN][MAXN], ans[MAXN][MAXN]; 102 103 inline int encode(int i, int j) { 104 if(i > j) swap(i, j); 105 return i * n + j; 106 } 107 108 int main() { 109 scanf("%d", &n); 110 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) scanf("%d", &mat[i][j]); 111 m = n * n; 112 int ss = n + m + 1, tt = ss + 1; 113 G.init(); 114 int sum = n * (n - 1) * (n - 2) / 6; 115 for(int i = 1; i <= n; ++i) { 116 for(int j = 1, tmp = 1; j < n; ++j, tmp += 2) G.add_edge(ss, i, 1, tmp); 117 for(int j = 1; j <= n; ++j) if(mat[i][j] != 0) 118 ans[i][j] = G.ecnt, G.add_edge(i, encode(i, j), 1, 0); 119 } 120 for(int i = 1; i <= m; ++i) G.add_edge(i + n, tt, 1, 0); 121 int x = G.min_cost_flow(ss, tt, tt); 122 printf("%d\n", sum - (x - n * (n - 1) / 2) / 2); 123 for(int i = 1; i <= n; ++i) { 124 for(int j = 1; j <= n; ++j) { 125 if(j != 1) printf(" "); 126 if(mat[i][j] != 2) printf("%d", mat[i][j]); 127 else { 128 if(G.flow[ans[i][j]] == 0) printf("1"); 129 else printf("0"); 130 } 131 } 132 puts(""); 133 } 134 }
View Code
转载于:https://www.cnblogs.com/oyking/p/3330462.html
BZOJ 2597 剪刀石头布(最小费用最大流)(WC2007)相关推荐
- bzoj 1834: [ZJOI2010]network 网络扩容【最大流+最小费用最大流】
第一问直接跑最大流即可.建图的时候按照费用流建,费用为0. 对于第二问,在第一问dinic剩下的残量网络上建图,对原图的每条边(i,j),建(i,j,inf,cij),表示可以用c的花费增广这条路.然 ...
- BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
- bzoj 2245 [SDOI2011]工作安排【最小费用最大流】
其实不用拆点,对于每个人我们假装他是\( s[i]+1 \)个点,可以由他向T点分别连\( s[i]+1 \)条边,容量为\( t[i][j]-t[i][j-1]\),由S点向所有产品i连容量为c[i ...
- bzoj 1070: [SCOI2007]修车【最小费用最大流】
一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...
- 有下界的最小费用可行流2.0(bzoj 3876: [Ahoi2014]支线剧情)
什么是有下界的最小费用可行流? 平时来讲都是最小费用最大流,也就是在满流的前提条件下费用尽可能的少,而最小费用可行流一般不要求满流,但是每条边都有最小流量要求(比如经过边e(u,v)的流量不能少于4等 ...
- BZOJ 1061 志愿者招募(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...
- 有上下限的最小费用可行流
例题 BZOJ 3876 题意,有N个点,并且有一些边,每个点必须要经过一次,但是不限经过次数,也就是有下界的情况,且下界为1,现在每次的起点都是1,问至少花费的代价,使得每次从1开始,终点不限的情况 ...
- 乌鲁木齐网络赛J题(最小费用最大流模板)
ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends 2017-09-09 17:24 243人阅读 评论(0) 收藏 举报 分类: 网络流(33) 版权声 ...
- POJ - 2516 Minimum Cost 最小费用最大流
题目链接 题意:给n,m,k表示商店数,储存店数,种类数 然后给n*k表示每个水果店需求每种种类的数量: 表示成 need[i][j] 再给m*k表示每个储存店每种种类数量: 表示成store[i][ ...
- pku The Windy's KM最小权匹配 or 最小费用最大流
http://poj.org/problem?id=3686 题意: 给定n个玩具,有m个车间,给出每个玩具在每个车间的加工所需的时间mat[i][j]表示第i个玩具在第j个车间加工所需的时间,规顶只 ...
最新文章
- SAP PM入门系列28 - IW67 Display Tasks
- Oracle 用户概念与基本操作
- Http协议中的Content-Length属性
- spark面试总结1
- UE选择合适的小区进行驻留以后
- JavaScript的Prototype实现
- Intellj(IDEA) warning no artifacts configured
- [CF1082E] Increasing Frequency
- 抖音城市美食算数报告
- HR怼程序员频繁跳槽,程序员竟这么回怼
- 进云仿美团外卖平台 v1.39源码
- 对象交互 模拟顾客点菜 c# 1614008435
- 如何选择RabbitMQ和Kafka
- mysql 存储过程实际应用,mysql 存储过程应用实例
- 图:出场顺序号码随机抽取及公开展示,并行随机抽取多个题目号码及公开展示-软件原型设计
- Windows+WSL+DockerDesktop下安装OpenV2X
- 面试阿里,看这一篇就够了!
- springboot中设置pageSize的默认值
- Python字典知识总结
- 谷歌经典bert模型从下载源码到运行成功
热门文章
- java 微信 回复_微信java 开发2 发送文本消息并回复
- 蓝桥杯单片机stc15f2k61s2矩阵按键中断扫描代码
- Java 基础知识总结(下)-王者笔记《收藏版》
- 服务禁止方法_Linux禁止ping以及开启ping的方法
- 怎样把文件传到华为云服务器,如何把文件传到云服务器上
- C++ 重载强制类型转换运算符
- Java try catch finally语句
- css的属性是变量是怎么表达,CSS自定义变量属性——像less,sass那样在css中使用变量(译)...
- iOS开发里面的4个层次
- 计算机科学和软件工程区别,计算机科学和软件工程的区别