NOIP模擬 電話線鋪設

2021-07-14 04:32:55 字數 1540 閱讀 5656

用什麼

首先,他需要把n個點連線起來且只用n-1條邊,還要使總邊權和最小,那麼很明顯是最小生成樹啦。

習慣用克魯斯卡爾演算法。

怎麼做

不過此處有乙個條件限制就是要加一條李牌的邊,就是只選n-2條王牌的邊。

那麼很顯然的是這n-2條邊是在最小生成樹上的邊。

所以先建立最小生成樹。

那麼我們只要列舉所有李牌的邊,替換一條李牌的邊或建立一條新邊,例如從x到y費用z,因為要使其是一顆樹,如果建立了一條新邊就需要在x,y到x,y的公共祖先上刪去一條王牌的邊才可以,且費用要盡量的大。

那麼我們在倍增求lca是也順便用倍增的方法把最大費用的一條邊及其的序號找出來即可。

注意

有一種情況是王牌的邊建完最小生成樹之後只有n-2條邊,所以需要進行特判。

#include

#include

#include

#include

#include

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

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

#define rep(i,a) for(i=first[a];i;i=next[i])

using namespace std;

const int maxn=800007;

int i,j,k,l,t,n,m,w,e,num,x,y,z;

int fa[maxn],ans,first[maxn],next[maxn],last[maxn],tot,chang[maxn],an[maxn];

int ans1,ans2,ab[maxn],b[maxn],c[maxn],f[maxn][20],g[maxn][20],aa,q[maxn][20],xu[maxn];

int ans3[maxn],ans4,bb,deep[maxn];

struct nodea[maxn];

bool cmp(node x,node y)

int gf(int

x)void add(int

x,int

y,int z,int

q)void dfs(int

x,inty)}

int lca(int

x,int

y)int main()

sort(a+1,a+1+num,cmp);

fo(i,1,l)

ans=0x7fffffff;

fo(i,1,num)

if(m==n-1)break;

}if(m==n-2)

dfs(1,0);

fo(j,1,19)fo(i,1,n)

fo(i,1,l)

printf("%d\n",ans1);

}

架設電話線 題解

原題來自 usaco 2008 jan.silver 在郊區有 n 座通訊基站,p 條雙向電纜,第 i 條電纜連線基站 a i 和 b i 特別地,1 號基站是通訊公司的總站,n 號基站位於一座農場中。現在,農場主希望對通訊線路進行公升級,其中公升級第 i 條電纜需要花費 l i 公司正在舉行優惠活...

架設電話線 二分答案 SPFA

description farmer john打算將 線引到自己的農場,但電信公司並不打算為他提供免費服務。於是,fj必須為此向電信公司支付一定的費用。fj的農場周圍分布著n 1 n 1,000 根按1 n順次編號的廢棄的 線 杆,任意兩根 線桿間都沒有 線相連。一共p 1 p 10,000 對 線...

二分答案 spfa 架設電話線

架設 線 phoneline 題目描述 farmer john打算將 線引到自己的農場,但電信公司並不打算為他提供免費服務。於是,fj必須為此向電信公司支付一定的費用。fj的農場周圍分布著n 1 n 1,000 根按1.n順次編號的廢棄的 線桿,任意兩根 線桿間都沒有 線相連。一共p 1 p 10,...