试题编号: | 201412-4 |
试题名称: | 最优灌溉 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。 输入格式 输入的第一行包含两个正整数n, m,分别表示麦田的片数和雷雷可以建立的水渠的数量。麦田使用1, 2, 3, ……依次标号。 输出格式 输出一行,包含一个整数,表示灌溉所有麦田所需要的最小费用。 样例输入 4 4 样例输出 6 样例说明 建立以下三条水渠:麦田1与麦田2、麦田2与麦田4、麦田4与麦田3。 评测用例规模与约定 前20%的评测用例满足:n≤5。 |
问题链接:CCF201412-4 最优灌溉
问题分析:最小生成树的模板题
程序说明:程序使用prim算法进行求解
提交后得100分的C++程序:
#include<iostream>
#include<cstring>
using namespace std;
const int N=1003;
const int INF=0x3f3f3f3f;
int g[N][N],dist[N];
int prim(int n)//n表示水渠的数量
{
bool vis[N];
memset(vis,false,sizeof(vis));
for(int i=2;i<=n;i++)
dist[i]=g[1][i];
dist[1]=0;
vis[1]=true;
int mst=0;
for(int i=1;i<n;i++){
int temp=INF,k=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&dist[j]<temp)
temp=dist[k=j];
if(k==0)
return -1;//不存在最小生成树
mst+=dist[k];
vis[k]=true;
//更新
for(int j=1;j<=n;j++)
if(!vis[j]&&dist[j]>g[k][j])
dist[j]=g[k][j];
}
return mst;
}
int main()
{
int n,m,u,v,w;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=(i==j)?0:INF;
while(m--){
scanf("%d%d%d",&u,&v,&w);
if(g[u][v]>w)
g[u][v]=g[v][u]=w;
}
//prim算法
int mst=prim(n);
if(mst!=-1)
printf("%d\n",mst);
return 0;
}