[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)可以跳跃到结点 ...
随机推荐
- Codeforces Round #321 (Div. 2) E Kefa and Watch (线段树维护Hash)
E. Kefa and Watch time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Wannafly Union Goodbye 2016-A//初识随机化~
想来想去还是把这个题写下来了.自己在补题遇到了许多问题. 给出n(n<=1e5)个点,求是否存在多于p(p>=20)×n/100的点在一条直线上... 时限20s,多组数据,暴力至少n^2 ...
- python_79_模块定义导入优化
''' 1.定义 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件 (文件名:test.py,对应的模块名:test. import ...
- Hicharts图表的使用
Hicharts图表的使用 引用 在4.0之后就不需要jQuery了,z这里是用ajax向后台发送数据 引入js或者CDN,这里采用的是引入js的方式 在Hicarts文件中的index中查看相应的图 ...
- java,求1-100以内所有偶数的和。
package study01; public class Even { public static void main(String[] args) { int sum = 0; for (int ...
- lua 分割字符串
-- 参数:待分割的字符串,分割字符 -- 返回:子串表.(含有空串) function split(str, split_char) local sub_str_tab = {} while tru ...
- 如何使用postman做接口测试
1.get请求传参 只要是get请求都可以在浏览器中直接发: 在访问地址后面拼 ?key=value&key=value 例如: 在浏览器中直接输入访问地址,后面直接拼需要传给服务器的参数 ...
- OC8051项目启动
- PHP redis使用命令
很有用;以下是redis官方提供的命令使用技巧: 下载地址如下: https://github.com/owlient/phpredis(支持redis 2.0.4) Redis::__constru ...
- oop中 限制文件类型和大小
<?php /** * Created by IntelliJ IDEA. * User: jiabinwang * Date: 7/5/18 * Time: 8:46 PM */ namesp ...