1. 程式人生 > >洛谷2765:[網絡流24題]魔術球問題——題解

洛谷2765:[網絡流24題]魔術球問題——題解

num void 答案 algo main cnblogs print 鏈表 log

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/+

+++++++++++++++++++++++++++++++++++++++++++

洛谷2765:[網絡流24題]魔術球問題——題解