洛谷2765:[网络流24题]魔术球问题——题解
https://www.luogu.org/problemnew/show/P2765#sub
假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。
(1)每次只能在某根柱子的最上面放球。
(2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。
试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可放11 个球。
参考:洛谷前两页题解。
一种做法是贪心,即能放在前面柱子的球就放在前面,然而正确性不好证(洛谷题解有证明)
然后考虑网络流。
一个很显然的想法就是对数拆点,左点连向右点当且仅当这两个数符合条件。我们对这个图跑一遍最大流就相当于找出最大匹配方案,这些匹配就相当一个链表,这样我们就知道了哪些球是放在一起的了。
之后做的就是尝试答案,直到链表超过n个为止。
#include<cstdio> #include<cmath> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #include<cctype> using namespace std; const int N=5000; const int M=400000; const int INF=1e9; struct node{ int nxt,to,w; }edge[M]; int head[N],cnt=-1,S,T,re[N],nxt[N]; bool vis[N]; inline void add(int u,int v,int w){ edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt; edge[++cnt].to=u;edge[cnt].w=0;edge[cnt].nxt=head[v];head[v]=cnt; } int lev[N],cur[N],dui[N]; bool bfs(int m){ int r=0; for(int i=1;i<=m;i++){ lev[i]=-1; cur[i]=head[i]; } dui[0]=S,lev[S]=0; int u,v; for(int l=0;l<=r;l++){ u=dui[l]; for(int e=head[u];e!=-1;e=edge[e].nxt){ v=edge[e].to; if(edge[e].w>0&&lev[v]==-1){ lev[v]=lev[u]+1; r++; dui[r]=v; if(v==T)return 1; } } } return 0; } int dinic(int u,int flow,int m){ if(u==m)return flow; int res=0,delta; for(int &e=cur[u];e!=-1;e=edge[e].nxt){ int v=edge[e].to; if(edge[e].w>0&&lev[u]<lev[v]){ delta=dinic(v,min(edge[e].w,flow-res),m); if(delta>0){ edge[e].w-=delta; edge[e^1].w+=delta; res+=delta; if(v!=m)nxt[u>>1]=v>>1; if(res==flow)break; } } } if(res!=flow)lev[u]=-1; return res; } int main(){ memset(head,-1,sizeof(head)); int n,now=0,num=0; scanf("%d",&n); S=1,T=N-5; while(now<=n){ num++; add(S,num<<1,1);add(num<<1|1,T,1); for(int i=1;i<num;i++){ int j=sqrt(i+num); if(j*j==i+num)add(i<<1,num<<1|1,1); } int ans=0; while(bfs(T))ans+=dinic(S,INF,T); if(!ans)re[++now]=num; } printf("%d\n",--num); for(int i=1;i<=n;i++){ int x=re[i]; if(vis[x])continue; while(x){ vis[x]=1; printf("%d ",x); x=nxt[x]; } puts(""); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++