2597: [Wc2007]剪刀石头布
2597: [Wc2007]剪刀石头布
分析:
费用流。
首先转化一下问题,整张图最优的情况是存在$C_n^3$个,即任意3个都行,然后考虑去掉最少不满足的三元环。
如果u赢了v,u向v连一条边,如果v有k条入边,那么说明少了$C_k^2$个三元环,所对每场比赛分配度数,求最小费用最大流。
具体地:S向每场比赛连容量为1,花费为0的边;每场比赛向两个人连容量为1,花费为0的边;每个人因为度数不同,花费不同,所以差分后建边。
还有一种随机化+迭代的做法。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = , INF = 1e9;
struct Edge { int from, to, nxt, cap, cost; } e[];
int head[N], pre[N], dis[N], q[], deg[N], id[][], A[][], P[N], tag[N], En = , S, T;
bool vis[N]; inline void add_edge(int u,int v,int f,int w) {
++En; e[En].from = u, e[En].to = v, e[En].cap = f, e[En].cost = w, e[En].nxt = head[u]; head[u] = En;
++En; e[En].from = v, e[En].to = u, e[En].cap = , e[En].cost = -w, e[En].nxt = head[v]; head[v] = En;
}
bool spfa() {
for (int i = ; i <= T; ++i) dis[i] = INF, vis[i] = false, pre[i] = ;
int L = , R = ;
q[++R] = S, vis[S] = true, dis[S] = ;
while (L <= R) {
int u = q[L ++]; vis[u] = false;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (dis[v] > dis[u] + e[i].cost && e[i].cap > ) {
dis[v] = dis[u] + e[i].cost;
pre[v] = i;
if (!vis[v]) q[++R] = v, vis[v] = true;
}
}
}
return dis[T] != INF;
}
int mcf() {
int Cost = , Flow = ;
while (spfa()) {
int now = 1e9;
for (int i = T; i != S; i = e[pre[i]].from)
now = min(now, e[pre[i]].cap);
for (int i = T; i != S; i = e[pre[i]].from)
e[pre[i]].cap -= now, e[pre[i] ^ ].cap += now;
Cost += dis[T] * now;
Flow += now;
}
return Cost;
}
int main() {
freopen("a.in", "r", stdin);
int n = read(), tot = n;
if (n < ) { printf(""); return ; }
for (int i = ; i <= n; ++i) {
for (int j = ; j <= i; ++j) read();
for (int j = i + ; j <= n; ++j) {
int x = read();
id[i][j] = ++tot;
if (x == ) deg[j] ++, tag[tot] = ;
else if (x == ) deg[i] ++, tag[tot] = ;
else { add_edge(tot, i, , ); P[tot] = En; add_edge(tot, j, , ); }
}
}
S = , T = tot + ;
for (int i = n + ; i <= tot; ++i) add_edge(S, i, , );
for (int i = ; i <= n; ++i)
for (int j = deg[i]; j < n - ; ++j) add_edge(i, T, , j);
int ans = n * (n - ) * (n - ) / ;
for (int i = ; i <= n; ++i)
ans -= deg[i] * (deg[i] - ) / ;
ans -= mcf();
printf("%d\n", ans);
for (int i = ; i <= n; ++i)
for (int j = i + ; j <= n; ++j) {
if (tag[id[i][j]]) A[i][j] = tag[id[i][j]] - ;
else A[i][j] = e[P[id[i][j]]].cap ? : ;
}
for (int i = ; i <= n; ++i, puts("")) {
for (int j = ; j < i; ++j) printf("%d ", A[j][i] ^ );
for (int j = i; j <= n; ++j) printf("%d ", A[i][j]);
}
return ;
}
2597: [Wc2007]剪刀石头布的更多相关文章
- bzoj 2597 [Wc2007]剪刀石头布——费用流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局:所以考虑算补集,则每个人对 ...
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- bzoj 2597: [Wc2007]剪刀石头布【最小费用最大流】
脑子不太清楚一个zz问题调了好久-- 首先正难则反,因为三元环好像没什么特点,就考虑让非三元环个数最小 考虑非三元环特点,就是环上一定有一个点的入度为2,联系整张图,三元环个数就是每个点C(入度,2) ...
- BZOJ 2597: [Wc2007]剪刀石头布(费用流)
传送门 解题思路 考虑全集-不能构成三元环的个数.如果三个点不能构成三元环,一定有一个点的入度为\(2\),继续扩展,如果一个点的度数为\(3\),则会失去3个三元环.对于一个点来说,它所产生的不能构 ...
- [Wc2007]剪刀石头布[补集转化+拆边]
2597: [Wc2007]剪刀石头布 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1157 Solved: ...
- [Wc2007]剪刀石头布
[Wc2007]剪刀石头布 http://www.lydsy.com/JudgeOnline/problem.php?id=2597 Time Limit: 20 Sec Memory Limit: ...
- [bzoj2597][Wc2007]剪刀石头布_费用流
[Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...
- 【BZOJ2597】[Wc2007]剪刀石头布 最小费用流
[BZOJ2597][Wc2007]剪刀石头布 Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之 ...
- 【bzoj 2597】[Wc2007]剪刀石头布(图论--网络流 最小费用最大流)
题目:在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道于统计有多少这样的 ...
随机推荐
- Linux man 命令详细介绍
知道linux帮助文件(man-pages,手册页)一般放在,$MANPATH/man 目录下面,而且按照领域与语言放到不同的目录里面. 看了上一章,要找那个命令使用相关手册,只要我们按照领域区分,到 ...
- linux下yum安装指定的mysql版本
因为直接使用yum安装的mysql会是默认版本5.1的版本 但是有的同学不满足又想要其他版本的怎么办呢? 曾时候我来提供一种方案(仅供参考): 我们可以使用rpm包来进行指定mysql版本的安装, ...
- [翻译] UPCardsCarousel
UPCardsCarousel UPCardsCarousel is a carousel with a cards based UI for iOS. UPCardsCarousel是一个旋转木马效 ...
- 2018年阿里巴巴关于java重要开源项目汇总
1.分布式应用服务开发的一站式解决方案 Spring Cloud Alibaba Spring Cloud Alibaba 致力于提供分布式应用服务开发的一站式解决方案.此项目包含开发分布式应用服务的 ...
- Python学习---Django拾遗180328
Django之生命周期 前台发送URL请求到Django的中间件进行内容校验,完成校验后到达路由映射文件url.py,然后调用视图函数views.py里面的函数进行内容处理[ 1.操作数据库进行数据读 ...
- Python学习---Form拾遗180322
Form操作之错误信息操作 1. 用户发送请求过来 2. for 循环对字段进行正则表达式的验证 fields.clean(value) 3. 自定义clean_字段() 进行名字段值正确性的校验 ...
- CMake: Could NOT find PkgConfig
转自http://www.ogre3d.org/forums/viewtopic.php?f=22&t=78490 Looking for OGRE... Could NOT find Pkg ...
- docker及服务器遇到的坑
目录 DNS不可用 修改docker查找源 容器保持固定ip 查看docker连接 容器间通信 容器拷贝数据 php连接docker mysql 8.0出错authentication method ...
- Hadoop HBase概念学习系列之行、行键(十一)
行是由列簇中的列组成.行根据行键依照字典顺序排序. HBase的行使用行键标识,可以使用行键查询整行的数据. 对同一个行键的访问都会落在同样的物理节点上.如果表包含2个列簇,属于两个列簇的文件还是保存 ...
- 复用$.ajax方式传递参数错误处理
1.封装后的方法,在 data:inData 传递参数的方式和一般不一样,如果不注意会出现错误. function getDataByJsonP(methName, inData, fn) { $.a ...