洛谷 P2765 魔術球問題

2021-08-16 20:21:32 字數 1403 閱讀 2938

有n個柱子,編號為1,2…….的小環,要將它們依次套在環上,要求直接接觸的兩小球的和為完全平方數,那麼最多可以套幾個小球。

首先可以貪心,如果可以套在其他小球上,則套在其他小球上,反之,套在柱子上,直到沒有多餘柱子,可以證明這是對的,但我覺得還是網路流的做法比較重要。

因為要依次取小球,那麼當答案為ans時,編號為1-ans的小球都被取走,我們可以用類似於洛谷 p1251 餐巾計畫問題的做法來拆點建圖。

將每個點拆成a,b兩點,因為放環有兩種可能,從s連一條邊到a,流量為1,表示直接將小球放在柱子底部,a再向t連一條流量為1的邊,保證該小球已經用過了,s向b連一條流量為1的邊,因為該小球並不會隨著它流到匯點而消失,b向編號大於它的且滿足和為完全平方數的點的a連邊,表示在這個小球上放小球。最後s向s連一條流量為柱子數的邊,用於限制柱子數。

在實際操作時,因為並不知道答案為多少,為了保證它能依次被取走,故要列舉小球個數,不斷的在殘餘網路上加入有關第i個小球的邊,並在參與網路的基礎上求最大流,若最大流不等於i,說明i-1為最優解。因為除了s->s的邊外,邊權均為一,因而可以列舉邊來計算流量。

另外此題不可以二分答案來做,因為從小到大列舉小球個數時可以利用殘餘網路加速,而二分則每次都要重新建圖,反而更劣。

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define n 4100

using

namespace

std;

int n,m,bb,first[n],deep[n],tmp,s,t,sum,ans,cur[n];

bool out[n];

struct bn

bn[200100];

queue

que;

inline

void add(int u,int v,int w)

inline

void ad(int u,int v,int w)

inline

bool bfs()

}return deep[t];

}int dfs(int now,int mn)

int res;

for(int &p=cur[now]; p!=-1; p=bn[p].next)

}return0;}

int main()

}ad(s,0,n);

for(i=1; i<=2000; i++)

if(ans!=i) break;

}cout

<1

printf("%d ",j);

for(q=j;;)

}if(p==-1) break;

}puts("");

}}

洛谷P2765 魔術球問題

問題描述 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,的球。1 每次只能在某根柱子的最上面放球。2 在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。程式設計任務 對於給定的n...

洛谷 P2765 魔術球問題

問題描述 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,的球。1 每次只能在某根柱子的最上面放球。2 在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。程式設計任務 對於給定的n...

P2765 魔術球問題

題目描述 問題描述 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,的球。1 每次只能在某根柱子的最上面放球。2 在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。程式設計任務 對...