NOIP 提高組2013 貨車運輸

2022-04-30 05:12:08 字數 1501 閱讀 5145

【演算法】最大生成樹+lca(倍增)

【題解】兩點間選擇一條路徑最小值最大的路徑,這條路徑一定在最大生成樹上,因為最大生成樹就是從邊權最大的邊開始加的

先求原圖的最大生成樹(森林),重新構圖,然後用乙個超級根連向每棵樹的根。

對於每個詢問,在樹上跑z=lca(x,y),答案就是x到z,z到y路上的最小值。

這個最小值可以在lca(倍增)的過程中順便維護(ms陣列),和祖先(倍增)陣列的維護方式類似。

ms[e[x].to][0]=e[i].w;

ms[x][i]=min(ms[x][i-1],ms[f[x][i-1]][i-1]);

求ans的時候,x,y每次向上推進都求一次ans=min(ans,...),具體可以看程式。

【注意】(只是提醒自己t_t)

1.每次要更新x,y的位置前先求ans。

2.無向邊建兩條,陣列要開大,而且後面求生成樹的時候要用建邊總數而不是原邊總數m!!!

3.超級根用0容易出錯,用比maxn大的數字即可。

4.重新構圖的新邊表和舊邊表各種變數注意區分

#include#include

#include

using

namespace

std;

const

int inf=0x3f3f3f3f,maxn=10010

;bool

ok[maxn];

struct cyceo[150010],e[150010

];int cnt,tot,head[maxn],heads[maxn],fa[maxn],f[maxn][16],ms[maxn][16

],vis[maxn],deep[maxn],n,m,q;

void insert(int u,int v,int

w)void ins(int u,int v,int

w)int getfa(int

x)bool

cmp(cyc a,cyc b)

void dfs(intx)}

}int lca(int x,int

y)int

main()

sort(eo+1,eo+cnt+1

,cmp);

for(int i=1;i<=n;i++)fa[i]=i;

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

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

if(!ok[getfa(i)])ok[fa[i]]=1,ins(10010

,fa[i],inf);

//for(int i=1;i<=tot;i++)printf("%d %d %d\n",e[i].from,e[i].to,e[i].w);

dfs(10010

); scanf("%d

",&q);

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

return0;

}

view code

NOIP 2013 提高組 貨車運輸

a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。第一行有兩個用乙個空格隔開的整數 n,m,表示 a 國有 n 座城市和 m 條道路。接下來 m ...

NOIP2013提高組 貨車運輸

noip2013 提高組 day1 試題。a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。第一行有兩個用乙個空格隔開的整數 n m,表示 a 國...

題解 NOIP2013 提高組 貨車運輸

使用演算法 堆優化 prim lca 大樣例題目鏈結 共有 n 個點,有 m 條邊來連線這些點,每條邊有權值。有 q 條類似於 u v 詢問,求一條從 u 到 v 的路徑使得路徑上的最小權值最大,求這個最大值。若不存在從 u 到 v 的路徑,則輸出 1 先求該圖的最大生成樹,因為需要使得該路徑上的最...