題目描述
村子間的小路年久失修,為了保障村子之間的往來,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_iui, viv_ivi , wiw_iwi 表示一條連線 (ui,vi)(u_i, v_i)(ui,vi) 的權值為叫的無向邊。
輸出格式
僅一行乙個整數表示答案。若無解輸出 −1-1−1 .
樣例樣例輸入
5 5 2
1 3 4
3 5 2
2 3 1
3 4 4
2 4 3
樣例輸出
9
1 #include 23using
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級父親標記 然後用這個點向外擴充套件更新...