p1222 Watering Hole
阿新 • • 發佈:2018-12-09
題目
描述 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;
}