長樂集訓 2017 Day8 修路 斯坦納樹

2022-05-06 09:18:15 字數 3361 閱讀 6699

題目描述

村子間的小路年久失修,為了保障村子之間的往來,aaa君決定帶領大家修路。

村子可以看做是乙個邊帶權的無向圖ggg, ggg 由 nnn 個點與 mmm 條邊組成,圖中的點從 1∼n1 \sim n1∼n 進行編號。現在請你選擇圖中的一些邊,使得 ∀1≤i≤d\forall 1 \leq i \leq d∀1≤i≤d , iii 號點和 n−i+1n - i + 1n−i+1號點可以通過你選擇出的那些邊連通,並且你要最小化選出的所有邊的權值和。請你告訴aaa君這個最小權值和。

輸入格式

第一行三個整數 nnn, mmm , ddd 表示圖中的點數、邊數與限制條件。

接下來 mmm 行每行三個整數 uiu_iu​i​​, viv_iv​i​​ , wiw_iw​i​​ 表示一條連線 (ui,vi)(u_i, v_i)(u​i​​,v​i​​) 的權值為叫的無向邊。

輸出格式

僅一行乙個整數表示答案。若無解輸出 −1-1−1 .

樣例樣例輸入

5 5 2 

1 3 4

3 5 2

2 3 1

3 4 4

2 4 3

樣例輸出

9

1 #include 2

3using

namespace

std;

4const

int maxn = 1e4+500;5

const

int inf = 1

<<29;6

intfa[maxn];

7int

n,m,d,st;

8int

s[maxn];

9bool inq[maxn][1

<<8

];10

int f[maxn][1

<<8];//

f[i][j]根節點為i,連同狀態為j的最小生成樹

11int g[1

<<8];//

g 連同狀態為j的最小生成樹

12int

ehead[maxn],ecnt;

13 queueint,int> >que;

14 inline void read(int&a)

15struct

edge

16edg[maxn*2

];19

bool upd(int &u,int

v)20

23void add (int u,int v,int

w)24

;26 ehead[u]=ecnt;

27 edg[++ecnt] =(edge);

28 ehead[v]=ecnt;

2930}31

int findd (int

x)32

36void union (int x,int

y)3744}

45void

spfa ()

4659}60

}61}62

}63bool check (int

j)64

70return

true;71

}72void

init ()

7379

intmain()

8097

for (int i=1;i<=d;++i)

106}

107for (int j=0;j<=st;++j)

112}

113for (int i=1;i<=n;++i)

118}

119spfa();

120}

121for (int j=1;j<=st;++j)

127for (int j=1;j<=st;++j)

131}

132 printf("

%d\n

",g[st]);

133return0;

134 }

**:1. 什麼是斯坦納樹?

斯坦納樹問題是組合優化學科中的乙個問題。將指定點集合中的所有點連通,且邊權總和最小的生成樹稱為最小斯坦納樹(minimal steiner tree),其實最小生成樹是最小斯坦納樹的一種特殊情況。而斯坦納樹可以理解為使得指定集合中的點連通的樹,但不一定最小。

2. 如何求解最小斯坦納樹?

可以用dp求解,dp[i][state]表示以i為根,指定集合中的點的連通狀態為state的生成樹的最小總權值。

轉移方程有兩重:

第一重,先通過連通狀態的子集進行轉移。

dp[i][state]=min 

列舉子集的技巧可以用 for(sub=(state-1)&state;sub;sub=(sub-1)&state)。

第二重,在當前列舉的連通狀態下,對該連通狀態進行鬆弛操作。

dp[i][state]=min

為什麼只需對該連通狀態進行鬆弛?因為更後面的連通狀態會由先前的連通狀態通過第一重轉移得到,所以無需對別的連通狀態鬆弛。鬆弛操作用spfa即可。

複雜度 o(n*3^k+ce*2^k)

c為spfa複雜度中的常數,e為邊的數量,但幾乎達不到全部邊的數量,甚至非常小。3^k來自於子集的轉移sum (1<=i<=n),用二項式展開求一下和。

1/*2

* steiner tree:求,使得指定k個點連通的生成樹的最小總權值

3* st[i] 表示頂點i的標記值,如果i是指定集合內第m(0<=m4

* endst=1<5

* dptree[i][state] 表示以i為根,連通狀態為state的生成樹值6*/

7#define clr(x,a) memset(x,a,sizeof(x))89

int dptree[n][1

<10bool vis[n][1

<11 queueque;

1213

intinput()

1420

21void

initsteinertree()

2230

31void update(int &a,int

x)32

3536

void spfa(int

state)

3753}54

}55}56

57void

steinertree()

5867

if(dptree[i][j]!=-1

) 68 que.push(i),vis[i][j]=true;69

}70spfa(j);71}

72 }

LOJ6045 雅禮集訓 2017 Day8 價

標籤 最小割,網路流 題目傳送門 30分 爆搜 40分 加乙個特判 全部取 因為pi小於0 正解 最小割建圖 源點s向每個 藥連一條流量為pi inf的邊 藥向其對應的藥材連一條流量為inf的邊 每個藥材向匯點t連一條流量為inf的邊 然後跑dinic 因為存在負邊權,那麼要加入sum計算進入 藥的...

loj6045 雅禮集訓 2017 Day8 價

我們考慮最小割。我一開始覺得是裸的最小割,就直接s到每個 藥連up p i 的邊,藥到藥材連inf邊,藥材到t連up,然後得到了40分的好成績。之後我發現這是乙個假的最小割,最小割割的是代價或者得不到的收益,上面說的這種建圖左邊割掉的是收益,右邊割掉的是代價,然後當然就gg了。所以我們把p取相反數,...

湖南集訓day8

難度 可以先考慮一維,可知 模k意義下相同的字首和任意兩個相減都是k的倍數 問題等價於統計字首何種模k相同的數的對數。多維的時候二維字首和,壓行或者壓列,n 3可以解決。樹形dp可做,好難好難的樣子 考慮貪心 暗點的深度排序,每次拿出未被更新的最深的點把他的k級父親標記 然後用這個點向外擴充套件更新...