p1222 Watering Hole

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84893508

题目

描述 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;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84893508