cogs396 [网络流24题]魔术球问题简化版
2016-12-24 17:33
260 查看
这道题我一看 第一感觉感觉完全不可做跟网络流完全没有关系……
后来我就弃疗了 看了黄学长的博客QvQ
这道题好神啊
这道题是正确做法是转化为最小路径覆盖问题
我们枚举答案a 对于每一个答案 建点1..a
然后对于i<j且i+j为完全平方数连边 得到一个有向无环图
我们可以发现 每一根柱子其实对应着有向无环图上的一条路径
那么我们对这个有向无环图求最小路径覆盖
就可以算出最少用几根柱子了
实际操作的时候就枚举a 如果最小路径覆盖大于n就输出a-1
顺便说一下DAG的最小路径覆盖
我就不复制百科上的话了= = 自己解释一下
如果DAG有p个点 DAG对应二分图的最大匹配为m
则最小路径覆盖即为p-m
DAG对应二分图的建法是把原图的点p拆成p’和p” 如果原图中存在边pi->pj 那么就把二分图里的p’i和p”j相连 很简单吧= =
做法的正确性在于 我们首先可以发现 如果原图没有边 那么匹配为0 每个点单独做一个路径 最小路径覆盖即为p
每当匹配增加1的时候 就可以把这两个点合到一个路径里 这样最小路径覆盖就会减少1
以此类推 就可以得出结论
后来我就弃疗了 看了黄学长的博客QvQ
这道题好神啊
这道题是正确做法是转化为最小路径覆盖问题
我们枚举答案a 对于每一个答案 建点1..a
然后对于i<j且i+j为完全平方数连边 得到一个有向无环图
我们可以发现 每一根柱子其实对应着有向无环图上的一条路径
那么我们对这个有向无环图求最小路径覆盖
就可以算出最少用几根柱子了
实际操作的时候就枚举a 如果最小路径覆盖大于n就输出a-1
顺便说一下DAG的最小路径覆盖
DAG上的最小路径覆盖问题
最小路径覆盖的意思是在一个DAG上找到最少的路径 使得每一个点都只被一条路径覆盖到 单独的一个点也可以算作一个路径我就不复制百科上的话了= = 自己解释一下
如果DAG有p个点 DAG对应二分图的最大匹配为m
则最小路径覆盖即为p-m
DAG对应二分图的建法是把原图的点p拆成p’和p” 如果原图中存在边pi->pj 那么就把二分图里的p’i和p”j相连 很简单吧= =
做法的正确性在于 我们首先可以发现 如果原图没有边 那么匹配为0 每个点单独做一个路径 最小路径覆盖即为p
每当匹配增加1的时候 就可以把这两个点合到一个路径里 这样最小路径覆盖就会减少1
以此类推 就可以得出结论
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int MAXA=1605,N=MAXA*2,M=200001,S=N-1,T=N-2,INF=1e9; const double EPS=1e-3; int n=0; int head ,next[M],to[M],c[M],f[M],edge=0; int q[M],front=0,back=0,d ; inline void addEdge(int u,int v,int argc) { to[edge]=v,c[edge]=argc,next[edge]=head[u],head[u]=edge++; to[edge]=u,c[edge]=0,next[edge]=head[v],head[v]=edge++; } inline int isPs(int x) { return abs(sqrt(x)-int(sqrt(x))-0.0)<=EPS; } inline void build(int a) { addEdge(S,2*a-1,1); addEdge(2*a,T,1); for (int i=1;i<=a-1;++i) { if (isPs(i+a)) addEdge(2*i-1,a*2,1); } } int bfs() { front=back=0; memset(d,0,sizeof(d)); d[S]=1; q[back++]=S; while (front<back) { int x=q[front++]; for (int e=head[x];~e;e=next[e]) { int v=to[e]; if (!d[v] && c[e]>f[e]) { d[v]=d[x]+1; q[back++]=v; } } } return d[T]; } int dfs(int x,int mn) { if (x==T || !mn) return mn; int flow=0; for (int e=head[x];~e;e=next[e]) { int v=to[e]; if (c[e]>f[e] && d[v]==d[x]+1) { int f0=dfs(v,min(mn,c[e]-f[e])); f[e]+=f0; f[e^1]-=f0; flow+=f0; mn-=f0; if (!mn) return flow; } } if (mn) d[x]=0; return flow; } int dinic() { int flow=0; memset(f,0,sizeof(f)); while (bfs()) flow+=dfs(S,INF); return flow; } int main(void) { freopen("balla.in","r",stdin); freopen("balla.out","w",stdout); scanf("%d",&n); memset(head,-1,sizeof(head)); for (int i=1;i<=n;++i) build(i); for (int a=n+1;a<=1600;++a) { build(a); if (a-dinic()>n) { printf("%d\n",a-1); 4000 break; } } fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- COGS396. [网络流24题]魔术球问题(简化版
- [网络流24题][COGS396]魔术球问题简化版(最小割)
- 396. [网络流24题]魔术球问题(简化版
- cogs 396. [网络流24题]魔术球问题(简化版
- [网络流24题]魔术球问题(简化版
- [网络流24题]魔术球问题(简化版
- [网络流24题-2]cogs396魔术球问题
- [网络流24题] 04 魔术球问题 (有向无环图最小路径覆盖, 最大流)
- [网络流24题]魔术球问题 贪心||枚举答案+最小路径覆盖
- [网络流24题]魔术球问题(简化版) 最小路径覆盖+二分答案 + 很快的最大流
- 线性规划与网络流24——魔术球问题
- 【网络流24题】魔术球问题
- [网络流24题]魔术球问题(简化版)
- [网络流24题]魔术球问题
- 洛谷2765:[网络流24题]魔术球问题——题解
- 【网络流24题】魔术球问题 二分答案+最小路径覆盖
- 【网络流24题】No.4 魔术球问题 (二分+最小路径覆盖)
- 魔术球问题[网络流24题之4]
- 【网络流24题】魔术球问题
- [网络流24题]魔术球问题(简化版)