【Luogu】P2765魔术球问题(没看懂的乱搞)
这题……讲道理我没看懂。
不过我看懂题解的代码是在干嘛了qwq
题解是zhaoyifan的题解
然后……我来讲讲这个题解好了。
题解把值为i的球拆成了两个,一个编号是i*2,一个编号是i*2+1。
为什么编号要这么编呢?因为统计编号的时候好统计qwq
然后从起点向i*2连一条边,从i*2+1到终点连一条边。
然后对于能够跟他凑成完全平方数的连边。
然后跑最大流,如果发现这个球不能串进原来的柱子上,也就是说最大流没有变化,那么就新加一条柱子。
当柱子数超过n的时候就退出循环开始统计。
大概……是这样。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cctype>
#include<queue>
#include<cmath>
#define maxn 200020
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} bool calc(int x){ return sqrt(x)*sqrt(x)==x; } inline int count(int i){ return i&?i+:i-; } struct Edge{
int next,to,val;
}edge[maxn*];
int head[maxn],num;
inline void addedge(int from,int to,int val){
edge[++num]=(Edge){head[from],to,val};
head[from]=num;
}
inline void add(int from,int to,int val){
addedge(from,to,val);
addedge(to,from,);
} bool vis[maxn];
int dfn[maxn];
int list[maxn];
int road[maxn];
int Start,End; bool bfs(){
memset(vis,,sizeof(vis));
queue<int>q; q.push(Start);
vis[Start]=; dfn[Start]=;
while(!q.empty()){
int from=q.front(); q.pop();
for(int i=head[from];i;i=edge[i].next){
int to=edge[i].to;
if(vis[to]||edge[i].val==) continue;
vis[to]=; q.push(to);
dfn[to]=dfn[from]+;
}
}
return vis[End];
} int dfs(int x,int val){
if(x==End||val==) return val;
int flow=; vis[x]=;
for(int &i=list[x];i;i=edge[i].next){
int to=edge[i].to;
if(vis[to]||edge[i].val==||dfn[to]!=dfn[x]+) continue;
int now=dfs(to,min(val,edge[i].val));
edge[i].val-=now; edge[count(i)].val+=now; flow+=now; val-=now;
road[x>>]=to>>;
if(val<=) break;
}
if(flow!=val) dfn[x]=-;
return flow;
} int maxflow(){
int ans=;
while(bfs()){
memset(vis,,sizeof(vis));
for(int i=Start;i<=End;++i) list[i]=head[i];
int now=dfs(Start,0x7fffffff);
if(!now) break;
ans+=now;
}
return ans;
} int tot;
int cnt;
int New[maxn]; int main(){
End=;
int n=read();
while(tot<=n){
cnt++; add(Start,cnt*,); add(cnt*+,End,);
for(int i=sqrt(cnt)+;i*i<cnt*;++i)
add((i*i-cnt)*,cnt*+,);
int ans=maxflow();
if(ans==) New[++tot]=cnt;
}
printf("%d\n",--cnt);
memset(vis,,sizeof(vis));
for(int i=;i<=n;++i){
if(vis[New[i]]) continue;
int x=New[i]; vis[x]=;
while((x!=End>>)&&x){
printf("%d ",x);
x=road[x];
vis[x]=;
}
printf("\n");
}
return ;
}
【Luogu】P2765魔术球问题(没看懂的乱搞)的更多相关文章
- luogu P2765 魔术球问题 (最小路径覆盖)
大意:给定n根柱子, 依次放入1,2,3,...的球, 同一根柱子相邻两个球和为完全平方数, 求最多放多少个球. 对和为平方数的点连边, 就相当于求DAG上最小路径覆盖. #include <i ...
- luogu P2765 魔术球问题
题目中没有说球的上限是多少,只告诉了柱子,那么我们就应该以柱子为界去增加球,考虑将每两个能组成完全平方数的点连边,就形成了一个DAG(有向无环图),由于是DAG,可以转换为最小覆盖问题,即最多有n条路 ...
- P2765 魔术球问题
P2765 魔术球问题 贪心模拟就可以过.........好像和dinic没啥关系 找找规律发现可以贪心放.n又灰常小. 设答案=m 你可以$O(mn)$直接模拟过去 闲的慌得话可以像我用个$se ...
- 洛谷 P2765 魔术球问题 解题报告
P2765 魔术球问题 题目描述 问题描述: 假设有\(n\)根柱子,现要按下述规则在这\(n\)根柱子中依次放入编号为\(1,2,3,\dots\)的球. \((1)\) 每次只能在某根柱子的最上面 ...
- PAT 甲级 1031 Hello World for U (20 分)(一开始没看懂题意)
1031 Hello World for U (20 分) Given any string of N (≥) characters, you are asked to form the char ...
- 洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)
P2765 魔术球问题 题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2 ...
- P2765 魔术球问题 网络流二十四题重温
P2765 魔术球问题 知识点::最小点覆盖 这个题目要拆点,这个不是因为每一个球只能用一次,而是因为我们要求最小点覆盖,所以要拆点来写. 思路: 首先拆点,然后就是开始建边,因为建边的条件是要求他们 ...
- 洛谷P2765魔术球问题 最小路径覆盖
https://www.luogu.org/problemnew/show/P2765 看到这一题第一眼想到:这不是二分最大流吗,后来发现还有一种更快的方法. 首先如果知道要放多少个球求最少的柱子,很 ...
- 洛谷P2765 魔术球问题
题目链接:https://www.luogu.org/problemnew/show/P2765 知识点: 最大流 解题思路: 本题所有边的容量均为 \(1\). 从 \(1\) 开始加入数字,将这个 ...
随机推荐
- 基于Activiti5.15.1 自定义用户、组(User,Group)实现
基于Activiti5.15.1 自定义用户.组(User,Group)实现 本人刚接触Activiti,最近工作中需要将Activiti中原有的用户,组(ACT_ID_USER,ACT_ID_GRO ...
- UVA 1153 Keep the Customer Satisfied 顾客是上帝(贪心)
因为每增加一个订单,时间是会增加的,所以先按截止时间d排序, 这样的话无论是删除一个订单,或者增加订单,都不会影响已经选好的订单. 然后维护一个已经选好的订单的大根堆(优先队列),如果当前无法选择的话 ...
- GentleNet使用之详细图解[语法使用增强版]
目录 第一章 开发环境 第二章 简介 第三章 Gentle.Net-1.5.0 下载文件包介绍 第四章 使用步骤 第五章 源码下载 第一章.开发环境: Vs 2010 + Sql 2005 + Gen ...
- CentOS安装RabbitMQ步骤
1.安装gcc yum install gcc 安装 ncurses-devel yum install ncurses-devel 2.安装erlang 下载安装包 http://www.erlan ...
- appium---命令行启动appium
在客户端的appium长时间运行的时候,出产生一些数据.日志有可能会对appium的内存有所增长,严重的会使appium产生崩溃,这个时候就推荐使用通过cmd进行运行appium, 安装前提需要安装N ...
- SSH程序框架之Spring与HIbernate整合
spring整合hibernate 有两种方式 1.注解方式 2.xml方式实现 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory ...
- UICollectionView实现无限轮播
#import "KGNewsController.h"#import "KGNewsCell.h"#import "KGNews.h"#i ...
- C# 调用腾讯地图WebService API获取距离(一对多)
官方文档地址:https://lbs.qq.com/webservice_v1/guide-distance.html 代码: /// <summary> /// 获取距离最近的点的经纬度 ...
- 【SAM】bzoj5084: hashit
做得心 力 憔 悴 Description 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 Input 一行一个字符 ...
- Linux - NodeJS安装
1> 去NodeJS官网 https://nodejs.org/en/ 或 中文网 http://nodejs.cn/download/ 拷贝相应版本的安装文件,如下图: 2> 执行 wg ...