洛谷 P2765 魔術球問題(網路流)

2021-08-19 23:46:04 字數 1705 閱讀 7582

題目描述

«問題描述:

假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,…的球。

(1)每次只能在某根柱子的最上面放球。

(2)在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。

試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。

«程式設計任務:

對於給定的n,計算在n根柱子上最多能放多少個球。

輸入輸出格式

輸入格式:

第1 行有1個正整數n,表示柱子數。

輸出格式:

程式執行結束時,將n 根柱子上最多能放的球數以及相應的放置方案輸出。檔案的第一行是球數。接下來的n行,每行是一根柱子上的球的編號。

輸入輸出樣例

輸入樣例#1: 複製

4 輸出樣例#1: 複製

11 1 8

2 7 9

3 6 10

4 5 11

【think】

剛開始的時候,我不知道該怎麼處理那個球數量不一定的情況。

後來發現可以每次都跑一遍dinic,假如有超過柱子數量的小球不能夠找到之前的點,就可以跳出了。

建圖:

之前選擇乙個較大的數,對於不超過55的柱子數量,小球個數的最大。。maxn

源點:s(0)

匯點:t(2*maxn+1)

將每乙個小球都要拆分成兩個,也就是拆點。

然後分別與源點和匯點,建立容量為1的邊。

每次增加完乙個小球之後,都要跑一遍dinic,判斷是否符合條件。

#include

#define max 600000

#define inf 0x3f3f3f3f

using

namespace

std;

int level[max];

int iter[max];

int maxn = 72312;

int t = maxn*2+1;

struct edge

;int next[max];

int vis[max];

vector

g[max];

void add_edge(int from, int to, int cap)

void bfs(int s)}}

}int dfs(int v, int t, int flow)}}

return0;}

int max_flow(int s, int t)

}}int main()

}add_edge(num+maxn, t, 1);

int f = max_flow(0, t);//每次都要跑dinic,找到邊的數量

ans -= f;

if(ans>n)//如果ans現在的個數大於柱子數量,說明會有小球沒有地方放。

break;

}printf("%d\n", num-1);

memset(next, 0, sizeof(next));

for(int i=maxn;ifor(int j=0;jif(e.cap>0)}}

memset(vis, 0, sizeof(vis));

for(int i=1;iif(vis[i]==0)

printf("\n");}}

return

0;}

洛谷P2765 魔術球問題

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

洛谷 P2765 魔術球問題

有n個柱子,編號為1,2 的小環,要將它們依次套在環上,要求直接接觸的兩小球的和為完全平方數,那麼最多可以套幾個小球。首先可以貪心,如果可以套在其他小球上,則套在其他小球上,反之,套在柱子上,直到沒有多餘柱子,可以證明這是對的,但我覺得還是網路流的做法比較重要。因為要依次取小球,那麼當答案為ans時...

洛谷 P2765 魔術球問題

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