noip模擬題 慰問員工 cheer
阿新 • • 發佈:2019-02-10
【題目描述】
LongDD 變得非常懶, 他不想再繼續維護供員工之間供通行的道路. 道路被用來連
接 N(5 <= N <= 10,000)個房子, 房子被連續地編號為 1..N. 每一個房子都是一個
員工的家. LongDD 計劃除去 P(N-1 <= P <= 100,000)條道路中儘可能多的道路, 但
是還要保持房子之間的連通性. 你首先要決定那些道路是需要保留的 N-1 條道路.
第 j 條雙向道路連線了房子 S_j 和 E_j (1 <= S_j <= N; 1 <= E_j <= N; S_j != E_j),
而且走完它需要 L_j (0 <= L_j <= 1,000)的時間. 沒有兩個房子 是被一條以上的道
路所連線.
員工們非常傷心, 因為她們的交通系統被削減了. 你需要到每一個員工的住處去安
慰她們. 每次你到達第 i 個房子的時候(即使你已經到過), 你必須花去 C_i (1 <=
C_i <= 1,000)的時間和員工交談.
你需要從某一個房子出發( 這是供你選擇的),並 最終 回到 這個 房子。期間,你要經
過每個房子至少一次,並且當你經過某個房子的時候,你必須和這個房子裡的員工
交談(即使你已經到過).
假設 LongDD 採納了你的建議, 請計算出使所有員工都被安慰的最少時間.
【輸入格式】
* 第 1 行: 用空格隔開的兩個整數 N 和 P
* 第 2..N+1 行: 第 i+1 行包含了一個整數: C_i
* 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔開的三個整數: S_j, E_j 和 L_j
【輸入樣例】
5 7
10
10
20
6
30
1 2 5
2 3 5
2 4 12
3 4 17
2 5 15
3 5 6
4 5 12
【輸出格式】
* 第 1 行: 一個整數, 所需要的總時間(包含和在你所在的房子的員工的兩次談話
時間).
【輸出樣例】
最小生成樹的一道題目。
LongDD 變得非常懶, 他不想再繼續維護供員工之間供通行的道路. 道路被用來連
接 N(5 <= N <= 10,000)個房子, 房子被連續地編號為 1..N. 每一個房子都是一個
員工的家. LongDD 計劃除去 P(N-1 <= P <= 100,000)條道路中儘可能多的道路, 但
是還要保持房子之間的連通性. 你首先要決定那些道路是需要保留的 N-1 條道路.
第 j 條雙向道路連線了房子 S_j 和 E_j (1 <= S_j <= N; 1 <= E_j <= N; S_j != E_j),
而且走完它需要 L_j (0 <= L_j <= 1,000)的時間. 沒有兩個房子 是被一條以上的道
路所連線.
員工們非常傷心, 因為她們的交通系統被削減了. 你需要到每一個員工的住處去安
慰她們. 每次你到達第 i 個房子的時候(即使你已經到過), 你必須花去 C_i (1 <=
C_i <= 1,000)的時間和員工交談.
你需要從某一個房子出發( 這是供你選擇的),並 最終 回到 這個 房子。期間,你要經
過每個房子至少一次,並且當你經過某個房子的時候,你必須和這個房子裡的員工
交談(即使你已經到過).
假設 LongDD 採納了你的建議, 請計算出使所有員工都被安慰的最少時間.
【輸入格式】
* 第 1 行: 用空格隔開的兩個整數 N 和 P
* 第 2..N+1 行: 第 i+1 行包含了一個整數: C_i
* 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔開的三個整數: S_j, E_j 和 L_j
【輸入樣例】
5 7
10
10
20
6
30
1 2 5
2 3 5
2 4 12
3 4 17
2 5 15
3 5 6
4 5 12
【輸出格式】
* 第 1 行: 一個整數, 所需要的總時間(包含和在你所在的房子的員工的兩次談話
時間).
【輸出樣例】
176
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int father[1000005]; struct pp { int u,v,w; }e[1000005]; int find(int x) { if(father[x]!=x) father[x]=find(father[x]); return father[x]; } void UN(int x,int y) { int a,b; a=find(x); b=find(y); father[a]=b; } bool cmp(pp a,pp b) { return a.w<b.w; } int n,m,c[100005],k(0),kk(0),ans(0),minn(0x7f),o(0); int main() { freopen("cheer.in","r",stdin); freopen("cheer.out","w",stdout); scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d ",&c[i]); minn=min(minn,c[i]); } for(int i=1;i<=m;i++) { int x ,y, z; scanf("%d %d %d",&x,&y,&z); k++; e[k].u=x; e[k].v=y; e[k].w=z*2+c[x]+c[y]; } sort(e+1,e+1+m,cmp); for(int i=1;i<=n;i++) father[i]=i; while(o<n-1) { kk++; if(find(e[kk].u)!=find(e[kk].v)) { ans+=e[kk].w; UN(e[kk].u,e[kk].v); o++; } } printf("%d\n",ans+minn); return 0; }
最小生成樹的一道題目。