刷题总结——魔术球问题(ssoj最小路径覆盖+网络流)
题目:
题目描述
假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2 ,3,… 的球。
(1)每次只能在某根柱子的最上面放球。
(2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数。
试设计一个算法,计算出在 n 根柱子上最多能放多少个球。例如,在 4 根柱子上最多放 11 个球。
对于给定的 n,计算在 n 根柱子上最多能放多少个球。
输入格式
输入文件第 1 行有 1 个正整数 n(1<n<60),表示柱子数。
输出格式
输出 n 根柱子上最多能放的球数。
样例数据 1
备注
【样例说明】
最多能放 11 个球,下面 4 行,每行是一根柱子上的球的编号。
1 8
2 7 9
3 6 10
4 5 11
【思考以下输出样式】
将 n 根柱子上最多能放的球数以及相应的放置方案输出到文件中。
文件的第一行是球数。接下来的 n 行,每行是一根柱子上的球的编号。
题解:
首先可以想到这道题的策略肯定是向上枚举球的数量然后判断····
建图方法是:如果对于i<j有i+j为一个完全平方数,连接一条有向边(i,j)。该图是有向无环图,求最小路径覆盖。如果刚好满足最小路径覆盖数等于N,那么A是一个可行解,在所有可行解中找到最大的A,即为最优解。最小路径覆盖相关知识点如下:
有向无环图最小不相交路径覆盖
定义:用最少的不相交路径覆盖所有顶点。
定理:把原图中的每个点V拆成Vx和Vy,如果有一条有向边A->B,那么就加边Ax-By。这样就得到了一个二分图,最小路径覆盖=原图的节点数-新图最大匹配。
简单证明:一开始每个点都独立的为一条路径,总共有n条不相交路径。我们每次在二分图里加一条边就相当于把两条路径合成了一条路径,因为路径之间不能有公共点,所以加的边之间也不能有公共点,这就是匹配的定义。所以有:最小路径覆盖=原图的节点数-新图最大匹配。
因此每次枚举新的点加直接和之前的点枚加边即可···令外每次不用重新在图上跑网络流,记录一个group表示柱子数,和枚举的点数一起加减,然后用group减去新跑的流即可,这样就相当于枚举的点数减去在新图上完全新跑出的流(看不懂的看代码就可以了),即为最小路径覆盖
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int inf=1e+;
const int N=;
int src=,des=;
int group,num,n;
int first[N],next[N*],go[N*],rest[N*],tot=,lev[N],cur[N];
inline void comb(int a,int b,int c)
{
next[++tot]=first[a],first[a]=tot,go[tot]=b,rest[tot]=c;
next[++tot]=first[b],first[b]=tot,go[tot]=a,rest[tot]=;
}
inline bool bfs()
{
for(int i=src;i<=des;i++) cur[i]=first[i],lev[i]=-;
static int que[N],tail,u,v;
que[tail=]=src;
lev[src]=;
for(int head=;head<=tail;head++)
{
u=que[head];
for(int e=first[u];e;e=next[e])
{
if(lev[v=go[e]]==-&&rest[e])
{
lev[v]=lev[u]+;
que[++tail]=v;
if(v==des) return true;
}
}
}
return false;
}
inline int dinic(int u,int flow)
{
if(u==des)
return flow;
int res=,delta,v;
for(int &e=cur[u];e;e=next[e])
{
if(lev[v=go[e]]>lev[u]&&rest[e])
{
delta=dinic(v,min(flow-res,rest[e]));
if(delta)
{
rest[e]-=delta;
rest[e^]+=delta;
res+=delta;
if(res==flow) break;
}
}
}
if(flow!=res) lev[u]=-;
return res;
}
inline void maxflow()
{
while(bfs())
group-=dinic(src,inf);
}
int main()
{
//freopen("a.in","r",stdin);
scanf("%d",&n);
while(true)
{
group++,num++;
for(int i=;i<num;i++)
if(sqrt(i+num)==(int)sqrt(i+num))
comb(i,num+,);
comb(num+,des,);
comb(src,num,);
maxflow();
if(group>n) break;
}
cout<<num-<<endl;
return ;
}
刷题总结——魔术球问题(ssoj最小路径覆盖+网络流)的更多相关文章
- LibreOJ 6003. 「网络流 24 题」魔术球 贪心或者最小路径覆盖
6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- cogs_396_魔术球问题_(最小路径覆盖+二分图匹配,网络流24题#4)
描述 http://cojs.tk/cogs/problem/problem.php?pid=396 连续从1开始编号的球,按照顺寻一个个放在n个柱子上,\(i\)放在\(j\)上面的必要条件是\(i ...
- LeetCode刷题: 【120】三角形最小路径和
1. 题目: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小 ...
- [Cogs728] [网络流24题#3] 最小路径覆盖 [网络流,最大流,二分图匹配]
建图:源点—>边的起点(集合1中的)—>边的终点(集合2中的)—>汇点,所有边权均为1, 计算最大流,最后枚举起点的出边,边权为0的即为匹配上的, 可以这样理解:每条边表示起点和终点 ...
- hiho# 1394最小路径覆盖 网络流拆点
题目传送门 思路: 观察到路径上除了终点起点以外的每个点出度和入度都为1,和网络流的拆点很像,所以就把每个点都拆成两个点,若存在一条路径$(u,v)$,则建一条$(u,v+n,1)$的边,然后求出最大 ...
- [loj #6003]「网络流 24 题」魔术球 二分图最小路径覆盖,网络流
#6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- 【网络流24题】No.4 魔术球问题 (二分+最小路径覆盖)
[题意] 假设有 n 根柱子, 现要按下述规则在这 n 根柱子中依次放入编号为 1, 2, 3, ¼的球.( 1)每次只能在某根柱子的最上面放球.( 2)在同一根柱子中,任何 2 个相邻球的编号之和为 ...
- Libre 6003 「网络流 24 题」魔术球 (网络流,最大流)
Libre 6003 「网络流 24 题」魔术球 (网络流,最大流) Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只 ...
- LOJ6003 - 「网络流 24 题」魔术球
原题链接 Description 假设有根柱子,现要按下述规则在这根柱子中依次放入编号为的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法 ...
随机推荐
- Yii 2.0排序功能的使用
在Yii2.0项目的实际开发中,经常会遇到使用Yii2.0自带的排序功能.下面是排序功能的具体使用方法. 一.设置排序规则 注意引入Sort类,如:use yii\data\Sort; // 设置排序 ...
- GoAccess参数选项
GoAccess - 1.2 Usage: goaccess [filename] [ options ... ] [-c][-M][-H][-q][-d][...]The following opt ...
- Ubuntu 14.04 配置confluence破解
1. 配置java环境,请参展我的另一篇博客 http://www.cnblogs.com/youran-he/p/8607155.html 2. 下载文件 https://pan.baidu.com ...
- 在SAP CRM WebClient UI中用javascript触发ABAP event
环境:SAP CRM WebClient UI 需求:在WebClient UI里不通过用户手动点击,而是使用JavaScript代码自动触发ABAP后台的代码. 解决方案: 1. 定义一个hidde ...
- Python 学习日志9月20日
9月20日 周三 多大年龄了,还活得像个小孩.——急什么,人生又不长. 你习惯了思考宇宙星辰,一百年真的不长,一生也就不那么长,许多人的价值观念你也就无法理解.同样,许多人也无法理解你的价值观念,感兴 ...
- soapui测试https双向验证p12项目
1.准备好p12 和jsk秘钥文件 2.配置soapui ssl 其中: 1:jks就是放在trustStore那里,密码填写为 106075 2:p12放到keystore,密码填写:180000 ...
- Luogu P1782 旅行商的背包
题目传送门 卡常背包果然名不虚传 算法主体就是两种背包分开跑,先跑多重背包,再跑奇货 不知道为什么,这题二进制拆分好像要比单调队列优化快一些 然后这题毒瘤的地方就出来了: 如果一件物品的体积\(\ti ...
- 多数据源连接Oracle报错,linux熵池耗尽问题
最近碰到了个很有意思的问题,springboot加载多数据源,遇到了在启动时数据库连接报错的问题. 报错信息: The error occurred while executing a query 然 ...
- 获得Java中System对应一些属性值
public static void main(String[] args){ System.out.println("Java运行时环境版本:\n"+System.getProp ...
- 欧拉函数φ(x)简要介绍及c++实现
我还是很喜欢数论,从此吃喝不问,就此沉沦. 欧拉函数φ(x)的值为在[1,x)的区间内与x互质的数的个数 通式: 其中p1, p2……pn为x的所有质因数,x是不为0的整数.φ(1)=1. 注意 ...