【UOJ #171】【WC 2016】挑战NPC
http://uoj.ac/problem/171
带花树开花时的u和v一定要记清楚顺序,想好了再写,数据范围也要算好!
对每个筐子拆成3个点,连成一个三元环,对每个(u,v),让u和v的3个点都连边,这样跑一般图最大匹配(先增广每个球),可以发现所有的球都能放到一个筐子里,而且半空的筐子代表的三元环一定有一条边有匹配。
匹配总数=n+半空的筐子数,最大化匹配总数也相当于最大化半空的筐子数。
还可以发现三元环没必要连三条边,任选两个点连一条边也是一样的。
时间复杂度\(O(n^3)\)。
abclzr:“好神的建图啊,我一辈子也想不出来。”
reflash:“没关系,下辈子继续想。”
abclzr:“……”
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 603;
const int M = 100003;
struct node {int nxt, to;} E[M << 1];
int cnt, point[N], n, m, e, s[N], qu[N];
void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt;}
int tt[N], id[N], tot, fa[N], pre[N], Next[N];
int find(int x) {return fa[x] == x ? x : (fa[x] = find(fa[x]));}
int p, q, tim = 0, vis[N];
int findlca(int u, int v) {
++tim;
while (true) {
if (u) {
if (vis[u] == tim)
return u;
vis[u] = tim;
u = find(pre[Next[u]]);
}
swap(u, v);
}
}
void blossom(int u, int v, int lca) {
while (find(u) != lca) {
pre[u] = v;
v = Next[u];
if (s[v] == 1) {s[v] = 0; if (++q == N) q = 0; qu[q] = v;}
if (fa[u] == u) fa[u] = lca;
if (fa[v] == v) fa[v] = lca;
u = pre[v];
}
}
int match(int x) {
memset(s, -1, sizeof(int) * (tot + 1));
for (int i = 1; i <= tot; ++i) fa[i] = i;
p = 0; q = 1; s[qu[1] = x] = 0; pre[x] = 0;
int u, v;
while (p != q) {
if (++p == N) p = 0; u = qu[p];
for (int i = point[u]; i; i = E[i].nxt) {
v = E[i].to;
if (s[v] == -1) {
s[v] = 1; pre[v] = u;
if (!Next[v]) {
int last;
while (u) {
last = Next[u];
Next[u] = v; Next[v] = u;
u = pre[v = last];
}
return 1;
}
s[Next[v]] = 0; if (++q == N) q = 0; qu[q] = Next[v];
} else if (s[v] == 0 && find(u) != find(v)) {
int lca = findlca(fa[u], fa[v]);
blossom(u, v, lca);
blossom(v, u, lca);
}
}
}
return 0;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &n, &m, &e);
tt[0] = n - 2;
for (int i = 1; i <= m; ++i) {
tt[i] = tt[i - 1] + 3;
id[tt[i]] = id[tt[i] + 1] = id[tt[i] + 2] = i;
}
int u, v; tot = tt[m] + 2;
cnt = 0;
memset(point, 0, sizeof(int) * (tot + 1));
memset(Next, 0, sizeof(int) * (tot + 1));
for (int i = 1; i <= e; ++i) {
scanf("%d%d", &u, &v);
ins(u, tt[v]); ins(tt[v], u);
ins(u, tt[v] + 1); ins(tt[v] + 1, u);
ins(u, tt[v] + 2); ins(tt[v] + 2, u);
}
for (int i = 1; i <= m; ++i) ins(tt[i], tt[i] + 1), ins(tt[i] + 1, tt[i]);
int ans = 0;
for (int i = 1; i <= tot; ++i)
if (!Next[i])
ans += match(i);
printf("%d\n", ans - n);
for (int i = 1; i <= n; ++i)
printf("%d ", id[Next[i]]);
puts("");
}
return 0;
}
【UOJ #171】【WC 2016】挑战NPC的更多相关文章
- 「WC2016」挑战NPC
「WC2016」挑战NPC 解题思路 这个题建图非常厉害,带花树什么的只会口胡根本写不动,所以我写了机房某大佬教我的乱搞. 考虑把一个筐 \(x\) 拆成 \(x1,x2,x3\) 三个点,且这三个点 ...
- 【BZOJ4405】【WC2016】挑战NPC(带花树)
[BZOJ4405][WC2016]挑战NPC(带花树) 题面 BZOJ 洛谷 Uoj Description 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个 ...
- [WC2016]挑战NPC(一般图最大匹配)
[WC2016]挑战NPC(一般图最大匹配) Luogu 题解时间 思路十分有趣. 考虑一个筐只有不多于一个球才有1的贡献代表什么. 很明显等效于有至少两个位置没有被匹配时有1的贡献. 进而可以构造如 ...
- UOJ 171 【WC2016】挑战NPC
一开始还真没想到是一般图匹配这种模型(毕竟才会的带花树) 把每一个盒子拆成3个,每一个可以放置进它的小球分别向这三个点连边,然后这三个点在连成一个三元环,最终答案就是小球数目-匹配数. 由于是一般图, ...
- 【刷题】UOJ #171 【WC2016】挑战NPC
小 N 最近在研究 NP 完全问题,小 O 看小 N 研究得热火朝天,便给他出了一道这样的题目: 有 \(n\) 个球,用整数 \(1\) 到 \(n\) 编号.还有 \(m\) 个筐子,用整数 \( ...
- [UOJ171][WC2016]挑战NPC
uoj luogu bzoj sol 你可以列一个表格. 一个框子里放球的数量 0 1 2 3 对"半空框子"数量的贡献 1 1 0 0 把一个框子拆三个点.两两之间连边. 会发现 ...
- UOJ171 【WC2016】挑战NPC
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- [BZOJ]4405: [wc2016]挑战NPC(带花树)
带花树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...
- [bzoj4405][wc2016]挑战NPC
来自FallDream的博客,未经允许,请勿转载,谢谢. 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个球,用整数1到n编号.还有m个筐子,用整数1到m编号. ...
随机推荐
- 基于FPGA的HDTV视频图像灰度直方图统计算法设计
随着HDTV的普及,以LCD-TV为主的高清数字电视逐渐进入蓬勃发展时期.与传统CRT电视不同的是,这些高清数字电视需要较复杂的视频处理电路来驱动,比如:模数转换(A/D Converter).去隔行 ...
- Codeforces 321E Ciel and Gondolas
传送门:http://codeforces.com/problemset/problem/321/E [题解] 首先有一个$O(n^2k)$的dp. # include <stdio.h> ...
- bootstrap框架的搭建
bootstrap框架 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快 ...
- Tensorflow 2.0.0-alpha 安装 Linux系统
1.TensorFlow2.0的安装测试 Linux Tensorflow Dev Summit 正式宣布 Tensorflow 2.0 进入 Alpha 阶段. 基于 Anaconda 创建环境一个 ...
- Optimizing TLB entries for mixed page size storage in contiguous memory
A system and method for accessing memory are provided. The system comprises a lookup buffer for stor ...
- 【设计模式】原型模式(Prototype)
摘要: 1.本文将详细介绍原型模式的原理和实际代码中特别是Android系统代码中的应用. 纲要: 1. 引入原型模式 2. 原型模式的概念及优缺点介绍 3. 原型模式对拷贝的使用 4. 原型模式在A ...
- monkey测试===Monkey测试结果分析(系列三)转
Monkey测试结果分析 一. 初步分析方法: Monkey测试出现错误后,一般的差错步骤为以下几步: 1. 找到是monkey里面的哪个地方出错 2. 查看Monkey里面出错前的一些事件动作,并手 ...
- telnet如何保存输出内容到本地
telnet如何保存输出内容到本地 http://bbs.csdn.net/topics/391023327 一种将程序的标准输出重定向到telnet终端的方法 http://blog.chinaun ...
- c#上传文件时,当选择的文件为0kb,会验证不通过
FileUpload1.HasFile 当FileUpload1控件选择的文件为0KB时,FileUpload1.HasFile返回false
- 1002: 当不成勇者的Water只好去下棋了---课程作业---图的填色
1002: 当不成勇者的Water只好去下棋了 Time Limit: 1 Sec Memory Limit: 128 MB Description 由于魔王BOSS躲起来了,说好要当勇者的Wate ...