HDU 1863 畅通工程 最小生成树
思路:
比较典型的最小生成树的题目了、、在这里用求最小生成树的经典算法K(Kruskal)算法和P(Prim)算法。我的 K 算法用的是结构体来存图,P 算法用的是邻接矩阵来存图,K算法的复杂度是O(ElogE),比较适用于稀疏图,P算法的复杂的是O(V ^ 2),适合用稠密图。
以下是C++的K算法代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
using namespace std; const int MAXN = 2e3+ ;
int pre[MAXN];
int m,n; int Find(int x) //并查集
{
return x == pre[x] ? x :(pre[x] = Find(pre[x]));
} struct Node //存图
{
int u, v, w;
}cy[]; int mycmp(Node a,Node b)
{
return a.w < b.w;
} void mst()
{
for(int i = ; i < ; i++)
pre[i] = i;
} int kru()//算法的具体实现
{
int ans = ;
int cnt = ;
for(int i = ; i <= n; i++)
{
int fv = Find(cy[i].v);
int fu = Find(cy[i].u);
if(fv != fu)
{
pre[fv] = fu;
ans += cy[i].w;
cnt ++;
}
if(cnt == m -)
{
return ans;
break;
}
}
return -;
} int main()
{
//freopen("in.cpp","r",stdin);
while(~scanf("%d%d",&n,&m) && n)
{
mst();
for(int i = ; i <= n; i++)
scanf("%d%d%d",&cy[i].u, &cy[i].v, &cy[i].w);
sort(cy + , cy + n + , mycmp);
int ans = kru();
if(ans != -)
printf("%d\n",ans);
else
printf("?\n");
}
return ;
}
以下是C++的P算法代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
using namespace std; const int MAXN = ;
const int INF = 0x3f3f3f3f;
int edge[MAXN][MAXN]; //用于存放图
int used[MAXN];//用于标记点是否已加入到最小生成树那个的集合中
int lowcost[MAXN]; //用于存放集合外的点到集合内的点的最短距离,每加入一个点需要更新一次
int N,M; int prim(int start,int maxn) //利用prim算法计算最小生成树
{
memset(used, , sizeof(used));
for(int i = ; i <= maxn; i++)
{
lowcost[i] = edge[start][i];
}
used[start] = ;
int sumweight = ;
int ok = ;
for(int i = ; i <= maxn; i++)
{
int minn = INF ;
int v = -;
for(int j = ; j <= maxn; j++)
{
if(used[j] == && lowcost[j] < minn)
{
minn = lowcost[j];
v = j;
}
}
//cout << v << " ";
if(v != -)
{
ok++;
used[v] = ;
sumweight += lowcost[v];
for(int j = ; j <= maxn; j++)
{
if(used[j] == && lowcost[j] > edge[v][j])
{
lowcost[j] = edge[v][j];
}
}
}
}
if(ok == maxn -)
return sumweight;
return -;
} int main()
{
while(cin >> N >> M && N)
{
memset(edge, 0x3f, sizeof(edge));
while(N--)
{
int u, v, w;
cin >> u >> v >> w;
edge[u][v] = edge[v][u] = w;
}
int ans = prim(, M);
if(ans < ) cout << "?" <<endl;
else cout << ans << endl;
}
return ;
}
以下是JAVA的K算法
import java.util.Scanner;
import java.util.Comparator;
import java.util.Arrays;
import java.text.DecimalFormat; class Vge{
int u;
int v;
int w;
} class mycmp implements Comparator<Vge>{
public int compare( Vge A, Vge B ){
if( A.w - B.w != 0 )
return A.w - B.w;
else
return A.w - B.w;
}
} public class Main{
final static int MAXN = 100 + 3;
static int[] pre = new int[ MAXN ];
static Vge[] clg = new Vge[ MAXN * MAXN ];
public static void main( String[] args ){
Scanner sc = new Scanner( System.in );
int n, m;
while( sc.hasNextInt() ){
n = sc.nextInt();
m = sc.nextInt();
if( n == 0 ) break;
for( int i = 0; i < n; i++ ){
clg[ i ] = new Vge();
clg[ i ].u = sc.nextInt();
clg[ i ].v = sc.nextInt();
clg[ i ].w = sc.nextInt();
}
mst( m );
int ans = ksu( n, m );
if( ans == -1 ) System.out.println( "?" );
else System.out.println( ans );
}
sc.close();
}
public static void mst( int n ){
for( int i = 0; i <= n; i++ ){
pre[i] = i;
}
}
public static int find( int x ){
return x == pre[ x ] ? x : ( pre[ x ] = find( pre[ x ] ) );
}
public static int ksu( int n, int m ){
Arrays.sort( clg, 0, n, new mycmp() );
int cnt = 0;
int ans = 0;
for( int i = 0; i < n; i++ ){
int fu = find( clg[ i ].u );
int fv = find( clg[ i ].v );
if( fu != fv ){
ans += clg[i].w;
cnt ++;
pre [ fv ] = fu;
}
if( cnt == m - 1 ) return ans;
}
return -1;
}
}
HDU 1863 畅通工程 最小生成树的更多相关文章
- HDU 1863 畅通工程(最小生成树,prim)
题意: 给出图的边和点数,要求最小生成树的代价,注:有些点之间是不可达的,也就是可能有多个连通图.比如4个点,2条边:1-2,3-4. 思路: 如果不能连通所有的点,就输出‘?’.之前以为每个点只要有 ...
- hdu 1863 畅通工程 (并查集+最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863 畅通工程 Time Limit: 1000/1000 MS (Java/Others) M ...
- <hdu - 1863> 畅通工程 并查集和最小生成树问题
本题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863 Problem Description: 省政府“畅通工程”的目标是使全省任何两个村庄间都可以 ...
- hdu 1863 - 畅通工程(MST)
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 题解报告:hdu 1863 畅通工程
Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可 ...
- HDU 1863 畅通工程
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- HDU 1863 畅通工程(Prim算法求解MST)
题目: 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本.现 ...
- HDU 1863 畅通工程 克鲁斯卡尔算法
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 1863 畅通工程(Kruskal)
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
随机推荐
- Python SimpleHTTPServer简单HTTP服务器
搭建FTP,或者是搭建网络文件系统,这些方法都能够实现Linux的目录共享.但是FTP和网络文件系统的功能都过于强大,因此它们都有一些不够方便的地方.比如你想快速共享Linux系统的某个目录给整个项目 ...
- golang中从一个日期开始往后增加一段时间
废话少说上code, 这个是从当前日期开始,往后增加一个月时间 package main import ( "fmt" "time" ) func main() ...
- 《大道至简》第一章 编程的精义 java伪代码形式
愚公.这位名家身上,浓缩了项目组织者.团队经理.编程人员.技术分析师等众多角色的优秀素质. 愚公移山事件分析: 原始需求:惩山北之塞,出入之迂 项目沟通方式:聚室而某曰 项目目标:毕力平险,指通豫南, ...
- realloc在aarch64_be-gcc的奇怪表现
最近遇到一个使用aarch64_be-gcc编译的ssh服务器出现不能通过ssh1协议使用密钥+passphrase不能正常登陆的问题. (⊙o⊙)…不要奇怪为啥还在用SSH1,我也在奇怪.. 一顿捣 ...
- PTA 11-散列3 QQ帐户的申请与登陆 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/723 5-15 QQ帐户的申请与登陆 (25分) 实现QQ新帐户申请和老帐户登陆的简 ...
- GIS专业分析方法(待更新)
遗传算法 核密度估计 http://blog.163.com/zhuandi_h/blog/static/1802702882012111092743556/ http://blog.csdn.net ...
- Eclipse中一个Maven工程的目录结构 (MacOS)
1. 为什么写这篇文章 在之前的javaSE开发中,没有很关注Eclipse工程目录下的环境,总是看见一个src就点进去新建一个包再写一个class.以后的日子中也没有机会注意到一个工程到底是怎么组织 ...
- 多校4 lazy running (最短路)
lazy running(最短路) 题意: 一个环上有四个点,从点2出发回到起点,走过的距离不小于K的最短距离是多少 \(K <= 10^{18} 1 <= d <= 30000\) ...
- BZOJ2594 [Wc2006]水管局长数据加强版 【LCT维护最小生成树】
题目 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的 ...
- margin百分比,重叠和auto
一. margin百分比 1. 普通元素的百分比margin都是相对于容器的宽度计算 2. 绝对定位元素的百分比margin是相对于第一个定位祖先元素(relative/absolute/fixed) ...