生成樹 SCOI 2012 滑雪與時間膠囊

2021-08-26 08:35:04 字數 1654 閱讀 5709

題意:乙個圖,每個點有乙個高度hi

h

i,邊有邊權。從

1 1

號點開始,每次從

i' role="presentation" style="position: relative;">ii走到

j j

當且僅當存在一條

i' role="presentation" style="position: relative;">ii和

j j

之間的邊,且hi

>=hj

' role="presentation" style="position: relative;">h

i>=hj

hi>=hj

。當到達任意乙個點時,可以

0 0

花費回到之前走到的任意乙個點。要求滿足經過點數最大的前提下使得經過的總距離最小,求最大點數和最短距離。

首先是建圖:對於讀入的每一條邊,如果hi

>=hj

' role="presentation" style="position: relative;">h

i>=hj

hi>=hj

.,就連一條i到

j i到j

的有向邊。如果hi

<=hj

h

i<=hj

,就連一條j到

i j到i

的有向邊。這樣如果hi

=hj hi=

hj

,i,j i,j

之間就有一條雙向邊。

我們發現,回到之前走過的點,其實就是回溯的過程,所以我們從

1 1

號節點開始df

s' role="presentation" style="position: relative;">dfs

dfs,對於搜到的點,我們將它加入到新圖中,統計搜到的點的數量,就是最終要求的最大點數。

接下來我們在新圖上跑kr

uska

l kru

skal

求最小生成樹。對於排序部分,為保證有盡可能多的點在最小生成樹里,我們按點的高度為第一關鍵字從大到小排序,邊長為第二關鍵字從小到大排序,做最小生成樹時累計邊權求和即可。

#include

using

namespace

std;

struct node

e[2001000];

struct tree

a[2001000];

int n,m,num,head[200100],cnt,sum=1;

int f[201000],h[200100];

bool vis[1001000];

void add(int from,int to,long

long dis)

void dfs(int x)

}}int find(int x)

} bool cmp(tree n1,tree n2)

dfs(1);

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

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

f[i]=i;

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

}cout

<" "

0;}

SCOI2012 滑雪與時間膠囊 (最小生成樹)

題目描述 輸入的第一行是兩個整數n,m。接下來1行有n個整數hi,分別表示每個景點的高度。接下來m行,表示各個景點之間軌道分布的情況。每行3個整數,ui,vi,ki。表示編號為ui的景點和編號為vi的景點之間有一條長度為ki的軌道。輸出描述 輸出一行,表示a180285最多能到達多少個景點,以及此時...

SCOI2012 滑雪與時間膠囊

time limit 50 sec memory limit 128 mb submit 2362 solved 821 submit status discuss 膠囊消耗的情況下,以最短滑行距離滑到盡量多的景點的方案 即滿足經過景點數最大的前提下使得滑行總距離最小 你能幫他求出最短距離和景點數嗎...

SCOI2012 喵星球上的點名

有n個串,代表n個人的姓氏和名字,都是用很多個數字表示的,比如我姓1,2,3,4,名4,5,6,7。然後有m個點名串,如果點到了某個人的姓或名裡面的某一串,那個人就被點到,不過乙個人在乙個點名串中只能被點一次。比如點名串是2,3,4,我的姓中含有2,3,4,那麼我就會被叫到。求每個學生分別被叫到多少...