HDU1233 - 还是畅通工程 最小生成树,用了三种姿势AC

HDU1233 - 还是畅通工程 : http://acm.hdu.edu.cn/showproblem.php?pid=1233

用了三种姿势AC这题之后, 感觉对最小生成树的理解又更深了一层. 嗯, 让你们看看我用的是哪三种姿势

方法 1 :

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 5000;
int Father[MAXN],Ans;
int N,M;
int x,y;
struct Node{
	int Now,Next,Len;
}Edge[MAXN];
void Initial()
{
	M = (N * (N - 1)) / 2;
	Ans = 0;
	for(int i = 0;i < MAXN;i++)
		Father[i] = i;
}
bool Cmp(Node x,Node y)
{
	return x.Len < y.Len;
}
int Find(int x)
{
	return x == Father[x] ? x : Father[x] = Find(Father[x]);
}
int main()
{
	while(scanf("%d",&N),N)
	{
		Initial();
		for(int i = 1;i <= M;i++)
			scanf("%d%d%d",&Edge[i].Now,&Edge[i].Next,&Edge[i].Len);
		sort(Edge + 1,Edge + M + 1,Cmp);//注意是从1开始的编号,并按边的长度升序排序
		for(int i = 1;i <= M;i++)
		{
			int xx = Find(Edge[i].Now),yy = Find(Edge[i].Next);
			if(xx != yy)
				Father[xx] = yy,Ans += Edge[i].Len;
		}
		printf("%d\n",Ans);
	}
	return 0;
}
/*用并查集要用到结构体来储存节点和边,适合边少的情况 

方法 2 :

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 105;
const int Inf = 1<<30;
int Vis[MAXN],Dist[MAXN],Map[MAXN][MAXN],Ans,MIN;
int N,M;
int x,y,z;
void Initial()
{
	Ans = 0;
	M = (N * (N - 1) / 2);
	fill(Vis,Vis + MAXN,0);
	memset(Map,0,sizeof(Map));
//	fill(Dist,Dist + MAXN,Inf);
}
void Deal()
{
	Vis[1] = 1;
	for(int i = 1;i <= N;i++)//假定从编号1开始找
		Dist[i] = Map[i][1];
}
void Prim()
{
	Deal();
	int i,j,k;
	for(i = 2;i <= N;i++)
	{
		k = i;
		MIN = Inf;
		for(j = 2;j <= N;j++)//找出到A集合的最短距离MIN和编号k
			if(!Vis[j] && Dist[j] < MIN)
				MIN = Dist[j],k = j;
		Ans += MIN;
		Vis[k] = 1;//标记
		for(j = 2;j <= N;j++)//更新其他点j到A集合的最短距离Dist[j]
			if(Map[j][k] < Dist[j])
				Dist[j] = Map[j][k];
	}
	printf("%d\n",Ans);
}
int main()
{
	while(scanf("%d",&N),N)
	{
		Initial();
		for(int i = 1;i <= M;i++)
		{
			scanf("%d%d%d",&x,&y,&z);
			Map[x][y] = Map[y][x] = z;//无向图
		}
		Prim();
	}
	return 0;
}

方法 3 :

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 105;
const int Inf = 1<<30;
int Vis[MAXN],Dist[MAXN],Map[MAXN][MAXN],Ans,MIN;
int N,M;
int x,y,z;
struct Node{
	int v,len;
	bool friend operator <(Node x,Node y)
	{
		return x.len > y.len;
	}
};
void Initial()
{
	Ans = 0;
	M = (N * (N - 1) / 2);
	fill(Vis,Vis + MAXN,0);
	fill(Dist,Dist + MAXN,Inf);
	memset(Map,0,sizeof(Map));
}
void Prim()
{
	priority_queue<Node>P;//用优先队列,可以减少一定的运行时间
	Node t;
	t.v = 1,t.len = 0;
	P.push(t);
	while(!P.empty())
	{
		t = P.top();
		P.pop();
		if(Vis[t.v])continue;
		Vis[t.v] = 1;
		Ans += t.len;
		for(int i = 1;i <= N;i++)
			if(!Vis[i] && Map[i][t.v] < Dist[i])
			{
				Node p;
				Dist[i] = Map[i][t.v];
				p.v = i,p.len = Map[i][t.v];
				P.push(p);
			}

	}
	printf("%d\n",Ans);
}
int main()
{
	while(scanf("%d",&N),N)
	{
		Initial();
		for(int i = 1;i <= M;i++)
		{
			scanf("%d%d%d",&x,&y,&z);
			Map[x][y] = Map[y][x] = z;//无向图
		}
		Prim();
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-08 17:15:01

HDU1233 - 还是畅通工程 最小生成树,用了三种姿势AC的相关文章

hdu1233还是畅通工程 最小生成树(prim或kruskal)

Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小.请计算最小的公路总长度. Input 测试输入包含若干测试用例.每个测试用例的第1行给出村庄数目N ( < 100 ):随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离.为简

hdu1233 还是畅通工程 最小生成树

给出修建边的边权,求连通所有点的最小花费 最小生成树裸题 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 struct seg{ 7 int a,b,l; 8 bool operator <(const seg a)const{ 9 return l<a.l; 10 } 11 }s[5000]; 12 13 int n,fa[1

HDU1233 还是畅通工程 【最小生成树Prim】

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25591    Accepted Submission(s): 11370 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路

hdu 1879 继续畅通工程 (最小生成树)

继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12717    Accepted Submission(s): 5506 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列出

HDU 1863 畅通工程 (最小生成树)

畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16937    Accepted Submission(s): 7099 Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设

hdu-1863畅通工程 最小生成树克鲁斯卡尔算法kruskal(并查集实现)

畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16994    Accepted Submission(s): 7134 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

HDU1863 畅通工程---(最小生成树)

畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27972    Accepted Submission(s): 12279 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出

HDU1233 还是畅通工程【Prim】

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 27373    Accepted Submission(s): 12183 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路