網路流24題 魔術球問題(最小不相交路徑覆蓋)

2022-05-18 08:56:00 字數 1610 閱讀 7128

2023年3月7日3,5344

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

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

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

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

程式設計任務:

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

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

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

111 8

2 7 9

3 6 10

4 5 11

題解:這道題就是小的必須在大的下面,所以保證了dag的性質。

如果a,b(a

那麼a-->b連一條邊,那麼問題是不是轉化為,乙個dag最少需要多少條路徑(不想交),可以

完全覆蓋,如果超過了n則不行。

所以維護一下網路流,codevs上沒開spj,路徑方面處理一下。

1 #include2 #include3 #include4 #include5 #include6 #include7

8#define n 10007

9#define m 200007

10#define inf 1000000007

11using

namespace

std;

12 inline int

read()

1316

while(ch>='

0'&&ch<='9')

17return x*f;18}

1920

intn,s,t,ans,s;

21int cnt=1

,head[n],rea[m],val[m],next[m];

22int

dis[n],to[n],flag[n];

2324

void add(int u,int v,int

fee)

2531

bool

bfs()

3247}48

}49return0;

50}51int dfs(int u,int

mf)5266}

67if (!res) dis[u]=0;68

return

res;69}

70void

dinic()

7181

}82 ans-=res;83}

84int

main()

8598 printf("

%d\n

",s-1

);99

for (int i=1;i)

100for (int j=head[i];j!=-1;j=next[j])

101104

}105

for (int i=1;i)

106115 printf("\n"

);116 }//

十分巧妙的構思,轉化問題十分優秀。

117 }

網路流24題 魔術球問題

列舉答案轉化為判定性問題,然後最小路徑覆蓋,可以轉化成二分圖最大匹配,從而用最大流解決。列舉答案a,在圖中建立節點1.a。如果對於i具體方法可以順序列舉a的值,當最小路徑覆蓋數剛好大於n時終止,a 1就是最優解。由於是順序放球,每根柱子上的球滿足這樣的特徵,即下面的球編號小於上面球的編號。抽象成圖論...

魔術球問題(網路流24題)

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

網路流24題 魔術球問題

以珠子為點,滿足條件就兩兩連邊 那麼就是讓你求n條路徑最多能覆蓋多少節點。眾所周知,最小邊覆蓋 點總數 最大匹配 不會看這裡link 於是拆點跑二分圖即可 大概就是s向x連邊 滿足條件的點k向x 連邊 x 向t連邊 有兩種方式 1.我們輪流加點,每次在殘量網路跑最大流就可以了 2.我們二分答案,每次...