POJ-1287.Network(Kruskal + Prim + Prim堆优化)
Networking
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 19674 | Accepted: 10061 |
Description
Your task is to design the network for the area, so that there is a connection (direct or indirect) between every two points (i.e., all the points are interconnected, but not necessarily by a direct cable), and that the total length of the used cable is minimal.
Input
The maximal number of points is 50. The maximal length of a given route is 100. The number of possible routes is unlimited. The nodes are identified with integers between 1 and P (inclusive). The routes between two points i and j may be given as i j or as j i.
Output
Sample Input
1 0 2 3
1 2 37
2 1 17
1 2 68 3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32 5 7
1 2 5
2 3 7
2 4 8
4 5 11
3 5 10
1 5 6
4 2 12 0
Sample Output
0
17
16
26
Source
#include <cstdio>
#include <algorithm>
using namespace std; const int maxp = + , maxr = * / + ;
int p, r, ans, head[maxp], Rank[maxp];
struct Edge {
int u, v, w;
}edge[maxr]; void Make_Set() {
for(int i = ; i <= p; i ++) {
head[i] = i;
Rank[i] = ;
}
ans = ;
} int Find(int u) {
if(u == head[u]) return u;
return head[u] = Find(head[u]);
} void Union(int u, int v) {
int fu = Find(u), fv = Find(v);
if(fu == fv) return;
if(Rank[fu] > Rank[fv])
head[fv] = fu;
else {
head[fu] = fv;
if(Rank[fu] == Rank[fv]) Rank[fv] += ;
}
} bool cmp(Edge a, Edge b) {
return a.w < b.w;
} bool Is_same(int u, int v) {
return Find(u) == Find(v);
} void Kruskal() {
sort(edge + , edge + r + , cmp);
int cnt = ;
Make_Set();
for(int i = ; i <= r; i ++) {
if(!Is_same(edge[i].u, edge[i].v)) {
cnt ++;
ans += edge[i].w;
Union(edge[i].u, edge[i].v);
}
if(cnt == p - ) return;
}
} int main () {
while(~scanf("%d", &p) && p) {
scanf("%d", &r);
for(int i = ; i <= r; i ++) {
scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w);
}
Kruskal();
printf("%d\n", ans);
}
return ;
}
Prim + 邻接矩阵
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std; const int maxp = + , maxr = * / + , INF = 0x3f3f3f3f;
int p, r, ans, dist[maxp], G[maxp][maxp];
bool vis[maxp]; void Init() {
ans = ;
memset(vis ,false, sizeof vis);
for(int i = ; i <= p; i ++) {
for(int j = ; j <= p; j ++)
G[i][j] = INF;
}
} void prim(int source) {
dist[source] = ;
vis[source] = true;//初始状态下只有source为已经安装了network的点
for(int i = ; i <= p; i ++)
dist[i] = G[source][i];//初始化所有distance为source到他们的距离
for(int i = ; i <= p; i ++) {
int MIN = INF, k = -;
for(int j = ; j <= p; j ++) {//每次选择那个距离子最小生成树所有结点权值最小的结点,并将其连接Network
if(!vis[j] && MIN > dist[j]) {
k = j;
MIN = dist[j];
}
}
if(MIN == INF) return;//没找到就说明该此时已经没有可以探索的结点了
ans += MIN;
vis[k] = true;
for(int j = ; j <= p; j ++) {
if(!vis[j] && dist[j] > G[k][j])
dist[j] = G[k][j];//对于新增的结点k,动态更新最小生成树内结点到他们结点相邻的权值,很显然意思就是每新增一个结点就看是否此时会有一条更进的边可以到达j结点
}
}
} int main () {
int a, b, w;
while(~scanf("%d", &p) && p) {
scanf("%d", &r);
Init();
for(int i = ; i <= r; i ++) {
scanf("%d %d %d", &a, &b, &w);
if(w < G[a][b]) {//选择权值最小的那条边
G[a][b] = G[b][a] = w;
}
}
prim();
printf("%d\n", ans);
}
return ;
}
Prim + 最小堆优化 + 邻接表
这里堆是用STL优先队列实现的,我比较懒emm...(学了这么多需要堆优化的算法,结果现在连个最基本的堆都不会写,算法导论上说斐波纳挈堆优化的Prim超级快,所以打完国赛我会总结堆 + 斐波纳挈堆
还会更新出他们优化的算法)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std; typedef pair <int, int> pii;
struct Edge {
int to, cost;
friend bool operator < (const Edge &a, const Edge &b) {
return a.cost > b.cost;
}
};
const int maxp = + , maxr = * / + , INF = 0x3f3f3f3f;
int p, r, ans, dist[maxp];
bool vis[maxp];
vector <Edge> edge[maxp]; void addedge(int u, int v, int w) {
edge[u].push_back({v, w});
} void Queue_Prim(int source) {
memset(vis, false, sizeof vis);
for(int i = ; i <= p; i ++) dist[i] = INF;
dist[] = ans = ;
priority_queue <Edge> Q;
Q.push({source, dist[source]});
while(!Q.empty()) {
Edge now = Q.top();
Q.pop();
if(vis[now.to]) continue;
vis[now.to] = true;
ans += now.cost;
for(unsigned int i = ; i < edge[now.to].size(); i ++) {
int v = edge[now.to][i].to;
if(dist[v] > edge[now.to][i].cost) {
dist[v] = edge[now.to][i].cost;
Q.push({v, dist[v]});
}
}
}
} int main () {
int a, b, c;
while(~scanf("%d", &p) && p) {
scanf("%d", &r);
for(int i = ; i < r; i ++) {
scanf("%d %d %d", &a, &b, &c);
addedge(a, b, c);
addedge(b, a, c);
}
Queue_Prim();
for(int i = ; i <= p; i ++) edge[i].clear();
printf("%d\n", ans);
}
return ;
}
POJ-1287.Network(Kruskal + Prim + Prim堆优化)的更多相关文章
- 求最小生成树(暴力法,prim,prim的堆优化,kruskal)
求最小生成树(暴力法,prim,prim的堆优化,kruskal) 5 71 2 22 5 21 3 41 4 73 4 12 3 13 5 6 我们采用的是dfs的回溯暴力,所以对于如下图,只能搜索 ...
- Prim算法堆优化
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...
- hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】
题目1 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生 ...
- Electrification Plan 最小生成树(prim+krusl+堆优化prim)
题目 题意: 无向图,给n个城市,n*n条边,每条边都有一个权值 代表修路的代价,其中有k个点有发电站,给出这k个点的编号,要每一个城市都连到发电站,问最小的修路代价. 思路: prim:把发电站之间 ...
- POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)
Network Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14021 Accepted: 5484 Specia ...
- POJ 1861 Network (Kruskal求MST模板题)
Network Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14103 Accepted: 5528 Specia ...
- 图论之堆优化的Prim
本题模板,最小生成树,洛谷P3366 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边 ...
- 图论——最小生成树:Prim算法及优化、Kruskal算法,及时间复杂度比较
最小生成树: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.简单来说就是有且仅有n个点n-1条边的连通图. 而最小生成树就是最小权 ...
- 在 Prim 算法中使用 pb_ds 堆优化
在 Prim 算法中使用 pb_ds 堆优化 Prim 算法用于求最小生成树(Minimum Spanning Tree,简称 MST),其本质是一种贪心的加点法.对于一个各点相互连通的无向图而言,P ...
随机推荐
- TP框架中的M、D、C、I、A、S方法
M方法 M实例化参数是数据库的表名 //使用M方法实例化$User = M('User');//和用法$User = new /Think/Model ('User');等效//执行其他的数据操作$U ...
- js string相关方法
1>concat() //合并返回新的字符串 var a="么么么么",b="ssss"; a.concat(b) //"么么么么ss ...
- NodeJS、npm安装步骤和配置(windows版本)
https://jingyan.baidu.com/article/48b37f8dd141b41a646488bc.html 上面这个链接很详细了,怕它没了自己记一遍.我的简洁一点. 1. 打开no ...
- git flow工作流
https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md 说明: 个人在学习Git工作流的过程中,从原有的 SVN 模 ...
- Tensorflow学习笔记3:卷积神经网络实现手写字符识别
# -*- coding:utf-8 -*- import tensorflow as tf from tensorflow.examples.tutorials.mnist import input ...
- java四种引用类型以及使用场景详解
每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过“引用”.在 Java 中一切都被视为了对象,但是我们操作的标识符实际上是对象的一个引用(re ...
- [MethodImpl(MethodImplOptions.Synchronized)]、lock(this)与lock(typeof(...))
对于稍微有点经验的.NET开发人员来说,倘若被问及如何保持线程同步,我想很多人都能说好好几种.在众多的线程同步的可选方式中,加锁无疑是最为常用的.如果仅仅是基于方法级别的线程同步,使用System.R ...
- python tkinter实时显示曲线
from tkinter import *from tkinter import ttkimport time#画窗口root = Tk()root.geometry('1000x500')root. ...
- Reporting Services 配置工具
使用 Reporting Services 配置管理器可配置 Reporting Services 安装.如果使用“仅文件”选项安装报表服务器,则必须使用此工具来配置服务器,才能使用该服务器.如果使用 ...
- windows server IIS启用Windows authentication
双击打开IIS网站的authentication,如果有Windows authentication,直接右键启用即可,如果没有的话需要先安装一下Windows authentication,Micr ...