[luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)
枚举球的个数 num
如果 i < j && (i + j) 是完全平方数,那么 i -> j' 连一条边
再加一个超级源点 s,s -> i
再加一个超级汇点 t,i' -> t
那么当前可以放的柱子的最小数量就是最小不相交路径数
如果当前的最小不相交路径数 > num,break
求最大流的时候别忘了记录方案
——代码
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 10001
#define M 200001
#define mid 5000
#define min(x, y) ((x) < (y) ? (x) : (y)) int n, cnt, sum, ans, s, t = mid << ;
int head[N], to[M], next[M], val[M], suc[N], dis[N];
bool vis[N]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline void add(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
next[cnt] = head[x];
head[x] = cnt++;
} inline bool bfs()
{
int i, u, v;
std::queue <int> q;
memset(dis, -, sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == -)
{
dis[v] = dis[u] + ;
if(v == t) return ;
q.push(v);
}
}
}
return ;
} inline int dfs(int u, int maxflow)
{
if(u == t) return maxflow;
int i, v, d, ret = ;
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == dis[u] + )
{
d = dfs(v, min(val[i], maxflow - ret));
ret += d;
val[i] -= d;
val[i ^ ] += d;
if(d) suc[u] = v - mid;
if(ret == maxflow) return ret;
}
}
return ret;
} int main()
{
int i, j, now, num = ;
n = read();
memset(head, -, sizeof(head));
while()
{
num++;
add(s, num, ), add(num, s, );
add(num + mid, t, ), add(t, num + mid, );
for(i = ; i < num; i++)
if(sqrt(i + num) == (int)sqrt(i + num))
add(i, num + mid, ), add(num + mid, i, );
while(bfs()) sum += dfs(s, 1e9);
if(num - sum > n) break;
}
cnt = ;
memset(head, -, sizeof(head));
for(i = ; i < num; i++)
{
add(s, i, ), add(i, s, );
add(i + mid, t, ), add(t, i + mid, );
}
for(i = ; i < num; i++)
for(j = ; j < i; j++)
if(sqrt(i + j) == (int)sqrt(i + j))
add(j, i + mid, ), add(i + mid, j, );
while(bfs()) dfs(s, 1e9);
printf("%d\n", num - );
for(i = ; i < num; i++)
if(!vis[i])
{
now = i;
while(now)
{
printf("%d ", now);
vis[now] = ;
now = suc[now];
}
puts("");
}
return ;
}
[luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)的更多相关文章
- Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】
Consider a town where all the streets are one-way and each street leads from one intersection to ano ...
- P2172 [国家集训队]部落战争 二分图最小不相交路径覆盖
二分图最小不相交路径覆盖 #include<bits/stdc++.h> using namespace std; ; ; ; ], nxt[MAXM << ], f[MAXM ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- POJ Air Raid 【DAG的最小不相交路径覆盖】
传送门:http://poj.org/problem?id=1422 Air Raid Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- LuoguP2765 魔术球问题(最大流)
题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全 ...
- POJ1422Air Raid(二分图,最小不相交路径覆盖)
Air Raid Consider a town where all the streets are one-way and each street leads from one intersecti ...
- 刷题总结——魔术球问题(ssoj最小路径覆盖+网络流)
题目: 题目描述 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2 ,3,… 的球.(1)每次只能在某根柱子的最上面放球.(2)在同一根柱子中,任何 2 个相邻球的编号之和为 ...
- LuoguP2765 魔术球问题
LuoguP2765 魔术球问题 首先,很难看出来这是一道网络流题.但是因为在网络流24题中,所以还是用网络流的思路 首先考虑完全平方数的限制. 如果\(i,j\)满足\(i < j\) 且 $ ...
- HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...
随机推荐
- [VC]char 和 wchar_t相互转化
#include <windows.h> #include <stdio.h> //function: charTowchar //purpose:char to WCHAR ...
- What is a meta-class in Objective-C?
http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html In this post, I look at ...
- python_94_类变量实例变量
class Role: n=123#类变量 name='我是类name' list=[] def __init__(self,name,role,weapon,life_value=100,money ...
- JavaScript -- 内置对象数组
数组 创建数组的基本方式有两种: 1.使用 Array构造函数 语法:new Array() 小括号( )说明: (1)预先知道数组要保存的项目数量 (2)向Array构造函数中传递数组应包含的项 2 ...
- 关于SpringMVC注解
1.@RequestMapping RequestMapping是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址 ...
- lua 使用递归查找键值
function cc.exports.findValueByTbl(tbl,key)--递归方法,用于查找tbl中对应的键值 for k,v in pairs(tbl) do if k == key ...
- 响应者链和Hit-Test 机制
概念: 响应者 : 对用户交互动作事件进行响应的对象.响应者链:成为处理事件的响应者的先后顺序链. 1.Hit-Test 机制 当用户触摸(Touch)屏幕进行交互时,系统首先要找到响应者(Respo ...
- Java-JFrame-swing嵌套浏览器步骤
Java-JFrame-swing嵌套浏览器步骤 一.使用swing嵌套浏览器要实现的功能: 通过java的swing实现在一个窗体中嵌套一个浏览器,可以在这个浏览器中将另一个项目的内容显示出来,只需 ...
- 20.Yii2.0框架多表关联一对多查询之hasMany
目录 新手模式 hasMany关联模式查询 新建mode层Article.php 新建mode层Category.php 新建控制器HomeController.php 新手模式 用上次的查询结果,作 ...
- for_each_node(node)
遍历各个pg_data_t节点. 1.定义在include/linux/nodemask.h中 /* * Bitmasks that are kept for all the nodes. */ en ...