bzoj4006 JLOI2015 管道連線

2022-05-15 06:05:59 字數 3115 閱讀 5608

斯坦納樹。

一共有p個關鍵點:我們用乙個p位二進位制數表示是否包含這些關鍵點。

f[i][state]表示一定包含i點,至少包含關鍵點state的生成樹的最小費用,其中state是乙個二進位制數。

有2個轉移:

f[i][state]=min(其中s是state的子集)

f[i][state]=min(其中i號點和j號點有邊相連,費用為cost)

我們按state劃分階段,相同的state做spfa。

現在我們已經求出f了。

記dp[state]表示至少包含關鍵點state時的生成樹的最小費用,其實就是dp[state]=min(1<=i<=n)

我們還要判斷state是否合法,就是對於如果某種頻道出現在state中,那麼包含這種頻道的所有點都必須在state中。

但是現在dp[state]表示的還只是一棵生成樹。

答案可以是森林。

我們可以從state的子集更新:dp[state]=min(其中s是state的子集)

這樣就變成了森林了。

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include適用於cf,uoj,但不適用於poj

using

namespace

std;

typedef

long

long

ll;typedef

double

db;typedef pair

pii;

typedef complex

cp;#define mmst(a,v) memset(a,v,sizeof(a))

#define mmcy(a,b) memcpy(a,b,sizeof(a))

#define re(i,a,b) for(i=(a);i<=(b);i++)

#define red(i,a,b) for(i=(a);i>=(b);i--)

#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)

#define fi first

#define se second

#define m_p(a,b) make_pair(a,b)

#define p_b(a) push_back(a)

#define sf scanf

#define pf printf

#define two(k) (1<

inline t sqr(t x)

template

inline void upmin(t &t,t tmp)

template

inline void upmax(t &t,t tmp)

const db eps=1e-9

;inline

int sgn(db x)

const db pi=acos(-1.0

);inline

intgint()

for(;z!=eof && isdigit(z);res=res*10+z-'

0',z=getchar());

return (neg)?-res:res;

}inline ll gll()

for(;z!=eof && isdigit(z);res=res*10+z-'

0',z=getchar());

return (neg)?-res:res;

}const

int maxn=1000

;const

int maxm=3000

;const

int maxp=10

;const

int inf=0x3f3f3f3f

;int

n,m,p;

int now,first[maxn+100

];struct tedgeedge[2*maxm+100

];inline

void addedge(int u,int v,int

cost)

int bit[maxn+100

];int val[maxp+10

];int f[maxn+100][two(maxp)+10

];int vis[maxn+100][two(maxp)+10

];queue

q;inline

void

spfa()

}}int dp[two(maxp)+10

];#define wei(v,k) ((v>>((k)-1))&1)inline

int check(int

s)

intmain()

mmst(f,

0x3f

); re(i,

1,p)

int state,maxstate=two(p)-1

; re(state,

1,maxstate)

spfa();

}mmst(dp,

0x3f

); re(state,

1,maxstate)re(i,1

,n)upmin(dp[state],f[i][state]);

re(i,

1,maxstate)if

(check(i))

for(j=(i-1)&i;j;j=(j-1)&i)if

(check(j))

upmin(dp[i],dp[j]+dp[i-j]);

cout

return0;

}

view code

bzoj4006 JLOI2015 管道連線

傳送門 思路 一眼看上去很像斯坦納樹 但是限制稍有不同,只要每種顏色的點聯通即可 也就是說最後可能是森林 我聽說裸寫斯坦納樹有90 所以我們要在外面再套一層dp f i j 還是斯坦納樹的狀態,i是以i為根,j是狀態為j 先用斯坦納樹求出每種聯通狀況的最小費用 再設dp i 表示i這個狀態的最小費用...

bzoj4006 JLOI2015 管道連線

小銘銘最近進入了某情報部門,該部門正在被如何建立安全的通道連線困擾。該部門有 n 個情報站,用 1 到 n 的整數編號。給出 m 對情報站 ui vi 和費用 wi,表示情 報站 ui 和 vi 之間可以花費 wi 單位資源建立通道。如果乙個情報站經過若干個建立好的通道可以到達另外乙個情報站,那麼這...

bzoj 4006 JLOI2015 管道連線

time limit 30 sec memory limit 128 mb submit 1062 solved 576 submit status discuss 小銘銘最近進入了某情報部門,該部門正在被如何建立安全的通道連線困擾。該部門有 n 個情報站,用 1 到 n 的整數編號。給出 m 對情...