洛谷P2765 魔术球问题(最大流)
%%%KSkun大佬
话说明明是网络流……这题竟然还有打表找规律和纯贪心AC的……都是神犇啊……
来说一下如何建图。首先把每一个点拆成$X_i$和$Y_i$,然后$S$向$X_i$连一条容量为$1$的边,$Y_i$向$T$连一条容量为$1$的边。对于能和它组成完全平方数的点,从$A_j$向$B_i$连一条容量为$1$的边
然后考虑一下,加球不会导致柱子减少,所以可以枚举球数,然后每次加一个球,并跑一次最大流。如果新加入的球是能加到某一个柱子中的,那么这一次跑最大流是能得到新流的,只要能一直得到新流就一直加,当不能的时候,将柱子数加一(即将这一个球放到新的柱子上)
当柱子数等于$n+1$的时候退出,因为第$n+1$根柱子是刚被加的,所以在放最后一个球之前,所有的球都能放在$n$根柱子中,那么当前的球数减一就是答案
然后考虑一下怎么求方案。对于每一个点,我们可以定义$X_i=i*2,Y_i=i*2+1$,那么可以保证任意两个点的$X_i$和$Y_i$不会重复,且不管在哪一个点,除以二之后就是原来的点。那么我们可以在跑$dfs$的时候,把每一个可以往下走增广路的点连边(这就说明他们相加是完全平方数,可以放在同一个柱子里),那么就可以形成一个类似链表的东西。记录一下每一根柱子一开始放的球,然后沿着链表去找这个柱子上有哪些球就可以了
//minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);
}
const int inf=0x3f3f3f3f,N=,M=;
int head[N],Next[M],ver[M],edge[M],tot=,Pre[N];
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
}
int dep[N],s,t;
int n,m,cnt;
queue<int> q;
bool bfs(){
memset(dep,-,sizeof(dep));
dep[s]=,q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]<&&edge[i])
dep[v]=dep[u]+,q.push(v);
}
}
return ~dep[t];
}
int dfs(int u,int limit){
if(!limit||u==t) return limit;
int flow=,f;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=f;
Pre[u>>]=v>>;
if(!limit) break;
}
}
return flow;
}
int dinic(){
int flow=;
while(bfs()) flow+=dfs(s,inf);
return flow;
}
bool vis[N];int w[];
int main(){
n=read();
s=,t=;
while(m<=n){
++cnt;
add(s,cnt<<,),add(cnt<<|,t,);
for(int i=sqrt(cnt)+;i*i<(cnt<<);++i) add((i*i-cnt)<<,cnt<<|,);
int s=dinic();
if(!s) w[++m]=cnt;
}
print(--cnt),sr[++C]=;
for(int i=;i<=n;++i){
int u=w[i];
if(!vis[u]){
print(u),sr[++C]=,vis[u]=;
while(Pre[u]&&Pre[u]!=t>>){
u=Pre[u];
vis[u]=;
print(u),sr[++C]=;
}
sr[++C]=;
}
}
Ot();
return ;
}
洛谷P2765 魔术球问题(最大流)的更多相关文章
- 洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)
P2765 魔术球问题 题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2 ...
- 洛谷 P2765 魔术球问题 解题报告
P2765 魔术球问题 题目描述 问题描述: 假设有\(n\)根柱子,现要按下述规则在这\(n\)根柱子中依次放入编号为\(1,2,3,\dots\)的球. \((1)\) 每次只能在某根柱子的最上面 ...
- 洛谷P2765 魔术球问题(贪心 最大流)
题意 已经很简洁了吧. 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全 ...
- 洛谷P2765魔术球问题 最小路径覆盖
https://www.luogu.org/problemnew/show/P2765 看到这一题第一眼想到:这不是二分最大流吗,后来发现还有一种更快的方法. 首先如果知道要放多少个球求最少的柱子,很 ...
- 洛谷P2765 魔术球问题
题目链接:https://www.luogu.org/problemnew/show/P2765 知识点: 最大流 解题思路: 本题所有边的容量均为 \(1\). 从 \(1\) 开始加入数字,将这个 ...
- 洛谷 [P2765] 魔术球问题
贪心做法 每次尽可能选择已经放过球的柱子 #include <iostream> #include <cstdio> #include <cstring> #inc ...
- P2765 魔术球问题 网络流二十四题重温
P2765 魔术球问题 知识点::最小点覆盖 这个题目要拆点,这个不是因为每一个球只能用一次,而是因为我们要求最小点覆盖,所以要拆点来写. 思路: 首先拆点,然后就是开始建边,因为建边的条件是要求他们 ...
- P2765 魔术球问题
P2765 魔术球问题 贪心模拟就可以过.........好像和dinic没啥关系 找找规律发现可以贪心放.n又灰常小. 设答案=m 你可以$O(mn)$直接模拟过去 闲的慌得话可以像我用个$se ...
- [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码
[洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...
随机推荐
- Java和C#中的自定义元数据
Java的annotation和C#的Attribute,可用来为语言增加语义,定义元数据. 转自:http://rednaxelafx.iteye.com/blog/464889 http://bl ...
- krpano之背景音乐
步骤: 1.添加音乐控制插件 <!-- START:音乐控制 --> <plugin name="soundinterface" url="%SWFPA ...
- SqlConnection 无法设置连接超时
1.最有效的方法:对表格建立索引 2 在连接字符串中设置 Connection Timeout (默认15秒)3 设置 SqlCommand.CommandTimeout(默认是 30 秒)
- Visual Studio 2005 C# 读写Excel文件
做作业的时候查了一点儿资料, 用的vs2k5 读 excel 发现用起来非常简单...现在编程语言没话说! 项目-添加引用-COM-Microsoft Excel 12.0 Object Librar ...
- saltstack系列(三)——zmq订阅/发布模式
zmq订阅发布模式 server端代码: #coding=utf-8 ''''' 服务端,发布模式 ''' import zmq from random import randrange contex ...
- DLL卸载
[DLL卸载] 1.扫描Module.通过CreateToohelp32Snapshot.Module32First.Module32Next来完成. 2.通过FreeLibrary来卸载.通过在ke ...
- realsense and Mask_RCNN
###################librealsense and Mask_RCNN cd RealSennse/librealsense2018091501/librealsense/wrap ...
- 246. Strobogrammatic Number 上下对称的数字
[抄题]: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at u ...
- 2-javascript::笔记
0.位置: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 <body> 和 <head& ...
- 在Ubuntu安装Tomcat7.0及开机自动运行
在Ubuntu安装Tomcat7.0及开机自动运行 1.安装装Tomcat7.0 一般都是绿色版的,下载一个tomcat7.0解开到指定的目录上即可 然后进入tomcat目录的bin文件夹,执行 su ...