1. 程式人生 > >p1222 Watering Hole

p1222 Watering Hole

題目

描述 Description
Farmer John希望把水源引入他的N (1 <= N <= 300) 個牧場,牧場的編號是1~N.他將水源引入某個牧場的方法有兩個,一個是在牧場中打一口井,另一個是將這個牧場與另一個已經有水源的牧場用一根管道相連.
在牧場i中打井的費用是W_i (1 <= W_i <= 100000).
把牧場i和j用一根管道相連的費用是P_ij (1 <= P_ij <= 100000, P_ij = P_ji, P_ii = 0).
請你求出Farmer John最少要花多少錢才能夠讓他的所有牧場都有水源.
輸入格式 Input Format
* 第1行: 一個正整數N.

  • 第2~N+1行: 第i+1行包含一個正整數W_i.
  • 第N+2~2N+1行: 第N+1+i行包含N個用空格分隔的正整數,第j個數表示P_ij.
    輸出格式 Output Format
    總共有四個牧場.在1號牧場打一口井需要5的費用,在2或者3號牧場打井需要4的費用,在4號牧場打井需要3的費用.在不同的牧場間建立管道需要2,3或4的費用.
    樣例輸入 Sample Input

4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0

樣例輸出 Sample Output

9
輸出資料解釋
Farmer John需要在4號牧場打一口井,然後把所有牧場都用管道連到1號牧場上,總共的花費是3+2+2+2=9.

時間限制 Time Limitation
1s
來源 Source
usaco oct09 water

程式碼

#include<bits/stdc++.h>
#define maxnum 3010
using namespace std;
int n,ans,dist[maxnum],c[maxnum][maxnum];
inline int read()
{
	int f=1,num=0;
	char ch=getchar();
	while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
	while
(ch>='0'&&ch<='9') { num=(num<<1)+(num<<3)+ch-'0'; ch=getchar(); } return num*f; } bool v[maxnum]; void prim() { memset(v,0,sizeof(v)); v[0]=1;//地下已經在樹中 for (int i=1;i<=n;i++) { int x,minn=0x3f3f3f3f; for (int j=1;j<=n;j++) if (!v[j]&&dist[j]<minn) minn=dist[j],x=j; v[x]=1; ans+=minn; for (int y=1;y<=n;y++) if (!v[y]) dist[y]=min(dist[y],c[x][y]); }//prim跑一遍,所有牧場都加入到樹中 cout<<ans<<endl; } int main() { n=read(); for (int i=1;i<=n;i++) dist[i]=read();//打井的費用就是和地下相連的邊的權 for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) c[i][j]=read();//地上各邊的權 prim(); return 0; }