稠密图(邻接矩阵),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
全部函数通过杭电 1142,1162,1198,1213等题目测试。
- #include<iostream>
- #include<vector>
- #include<queue>
- #include<stack>
- #include<algorithm>
- #include<stdio.h>
- #include<stdlib.h>
- using namespace std;
- /*
- //函数集合声明下,方便查看
- void Dijkstra(const denseGraph& dg, int s);
- void spfa(const denseGraph& dg, int s);
- weightType prim(const denseGraph& dg, int s);
- void makeSet(int x);
- int findSet(int x);
- void unionSet(int x, int y);
- weightType kruskal(const denseGraph& dg);
- */
- //稠密图,邻接矩阵表示
- #define N 1000 //表示顶点数最大值
- #define NOEDGE 1000000 //表示无边,用于距离类求解中
- typedef double weightType; //表示带边权的类型
- //定义带权边类
- struct edge{
- int v, w;
- weightType val;
- edge(int v = -, int w = -, weightType val = NOEDGE) :v(v), w(w), val(val){}
- };
- //定义稠密图类
- struct denseGraph{
- int Vcnt, Ecnt; //顶点数,边数
- bool dg; //有向图 ?
- vector< vector<weightType> > adj; //邻接矩阵
- denseGraph(int v, bool dg = false) :adj(v), Vcnt(v), Ecnt(), dg(dg){
- for (int i = ; i < v; ++i)
- adj[i].assign(v, NOEDGE);
- }
- void insert(edge e){
- int v = e.v, w = e.w;
- weightType val = e.val;
- if (adj[v][w] == NOEDGE) ++Ecnt;
- adj[v][w] = val;
- if (!dg) adj[w][v] = val;
- }
- void show(){
- printf("Vcnt = %d, Ecnt = %d, Directed : %d\n", Vcnt, Ecnt, dg);
- for (int i = ; i < Vcnt; ++i){
- for (int j = ; j < Vcnt-; ++j)
- cout << adj[i][j] << ' ';
- cout << adj[i][Vcnt - ] << endl;
- }
- }
- };
- //Dijkstra算法
- weightType dDijkstra[N]; //存放所有顶点到 s 的最短路径距离
- int pDijkstra[N]; //pDijkstra[i],路径存在时,存放节点 i 的前驱,不存在时,-1
- void Dijkstra(const denseGraph &dg, int s)
- {
- bool visit[N]; //集合 S ,visit[i]=true, i 属于集合 S
- for (int i = ; i < dg.Vcnt; ++i){ //初始化
- visit[i] = false;
- dDijkstra[i] = dg.adj[s][i];
- pDijkstra[i] = dDijkstra[i] == NOEDGE ? - : s;
- }
- visit[s] = true; dDijkstra[s] = ;
- for (int i = ; i < dg.Vcnt - ; ++i){ //dg.Vcnt-1次选点
- int min = NOEDGE;
- int v = ;
- for (int j = ; j < dg.Vcnt; ++j){ //选距离最近点
- if (!visit[j] && dDijkstra[j] < min){
- v = j; min = dDijkstra[j];
- }
- }
- visit[v] = true;
- for (int j = ; j < dg.Vcnt; ++j){ //更新与 v 直接相连的顶点
- if (!visit[j] && min + dg.adj[v][j] < dDijkstra[j]){
- dDijkstra[j] = min + dg.adj[v][j];
- pDijkstra[j] = v;
- }
- }
- }
- }
- //最短路径 SPFA算法
- weightType dSpfa[N];
- int pSpfa[N];
- void spfa(const denseGraph& dg, int s)
- {
- bool visit[N];
- for (int i = ; i < dg.Vcnt; ++i){
- visit[i] = false;
- dSpfa[i] = NOEDGE;
- pSpfa[i] = -;
- }
- dSpfa[s] = ;
- int u;
- queue<int> q;
- q.push(s);
- while (!q.empty()){
- u = q.front(); q.pop();
- for (int i = ; i < dg.Vcnt; ++i){
- if (dSpfa[u] + dg.adj[u][i] < dSpfa[i]){
- dSpfa[i] = dSpfa[u] + dg.adj[u][i];
- pSpfa[i] = u;
- if (!visit[i])
- q.push(i);
- }
- }
- }
- }
- //最小生成树 prim
- weightType dPrim[N]; //存放所有顶点到 s 的最短路径距离
- weightType prim(const denseGraph& dg, int s)
- {
- weightType sum = ;
- bool visit[N];
- for (int i = ; i < dg.Vcnt; ++i){ //初始化
- visit[i] = false;
- dPrim[i] = dg.adj[s][i];
- }
- visit[s] = true; dPrim[s] = ;
- for (int i = ; i < dg.Vcnt - ; ++i){
- weightType min = NOEDGE;
- int v = ;
- for (int j = ; j < dg.Vcnt; ++j){ //选点
- if (!visit[j] && dPrim[j] < min){
- v = j; min = dPrim[j];
- }
- }
- sum += min;
- visit[v] = true;
- for (int j = ; j < dg.Vcnt; ++j){
- if (!visit[j] && dg.adj[v][j] < dPrim[j]){
- dPrim[j] = dg.adj[v][j];
- }
- }
- }
- return sum;
- }
- //并查集实现,点集[0,1,2,3,4,...,n-1]
- int parentSet[N];
- int rankSet[N];
- void makeSet(int x)
- {
- parentSet[x] = x;
- rankSet[x] = ;
- }
- void linkSet(int x, int y)
- {
- if (rankSet[x] > rankSet[y])
- parentSet[y] = x;
- else {
- parentSet[x] = y;
- if (rankSet[x] == rankSet[y])
- ++rankSet[y];
- }
- }
- int findSet(int x)
- {
- vector<int> v;
- while (parentSet[x] != x){
- v.push_back(x);
- x = parentSet[x];
- }
- for (int i = ; i < v.size(); ++i)
- parentSet[v[i]] = x;
- return x;
- }
- void unionSet(int x, int y)
- {
- linkSet(findSet(x), findSet(y));
- }
- //最小生成树 kruskal
- bool kruskalComp(const edge& a, const edge& b)
- {
- return a.val < b.val;
- }
- weightType kruskal(const denseGraph& dg)
- {
- weightType sum = ;
- edge e;
- vector<edge> ve;
- for (int i = ; i < dg.Vcnt; ++i)
- for (int j = ; j <= i; ++j)
- if (dg.adj[i][j]!=NOEDGE)
- ve.push_back(edge(i, j, dg.adj[i][j]));
- if (dg.dg){
- for (int i = ; i < dg.Vcnt; ++i)
- for (int j = i + ; j < dg.Vcnt; ++j)
- if(dg.adj[i][j]!=NOEDGE)
- ve.push_back(edge(i, j, dg.adj[i][j]));
- }
- sort(ve.begin(), ve.end(), kruskalComp);
- for (int i = ; i < dg.Vcnt; ++i)
- makeSet(i);
- for (int i = ; i < ve.size(); ++i){
- e = ve[i];
- int x = findSet(e.v);
- int y = findSet(e.w);
- if (x != y){
- unionSet(x, y);
- sum += e.val;
- }
- }
- return sum;
- }
- /*测试数据
- 5 6
- 1 3 2
- 1 4 2
- 3 4 3
- 1 5 12
- 4 2 34
- 5 2 24
- 7 8
- 1 3 1
- 1 4 1
- 3 7 1
- 7 4 1
- 7 5 1
- 6 7 1
- 5 2 1
- 6 2 1
- */
- int main()
- {
- int v, w, val, n, m;
- cin >> n >> m;
- denseGraph dg(n,true);
- while (m--){
- cin >> v >> w >> val;
- dg.insert(edge(v - , w - , val));
- }
- dg.show();
- cout << endl;
- for (int i = ; i < dg.Vcnt; ++i){
- spfa(dg, i);
- Dijkstra(dg, i);
- for (int i = ; i < dg.Vcnt; ++i)
- cout << dSpfa[i] << ' ';
- cout << endl;
- for (int i = ; i < dg.Vcnt; ++i)
- cout << dDijkstra[i] << ' ';
- cout << endl;
- for (int i = ; i < dg.Vcnt; ++i)
- cout << pSpfa[i] << ' ';
- cout << endl;
- for (int i = ; i < dg.Vcnt; ++i)
- cout << pDijkstra[i] << ' ';
- cout << endl << endl;
- }
- for (int i = ; i < dg.Vcnt; ++i)
- cout << prim(dg, i) << endl;
- cout << kruskal(dg) << endl;
- }
稠密图(邻接矩阵),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)的更多相关文章
- 几个小模板:topology, dijkstra, spfa, floyd, kruskal, prim
1.topology: #include <fstream> #include <iostream> #include <algorithm> #include & ...
- 2019 蓝桥杯国赛 B 组模拟赛 E 蒜头图 (并查集判环)
思路: 我们看条件,发现满足条件的子图无非就是一些环构成的图, 因为只有形成环,才满足边的两个点都在子图中,并且子图中节点的度是大于0的偶数. 那么如果当前有k个环,我们可以选2^k-1个子图,为什么 ...
- 图-连通分量-DFS-并查集-695. 岛屿的最大面积
2020-03-15 16:41:45 问题描述: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二 ...
- 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]
题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...
- 二分图建图,并查集求联通——二维等价性传递 cf1012B好题!
/* 模拟二分图:每个点作为一条边,连接的是一列和一行(抽象成一个点,列在左,行在右) 由题意得 a-b相连,a-c相连,b-d相连,那么d-c就不用再相连了 等价于把二分图变成联通的需要再加多少边 ...
- [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)
单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...
- 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
题目地址:http://ac.jobdu.com/problem.php?pid=1024 题目描述: 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但 ...
- fzu 2087并查集的运用求最小生成树的等效边
//对数组排序后,对于边相同并且边的两端不在一个集合内的一定是等效边或者必加边, //第一数数,第二合并集合 #include<stdio.h> #include<stdlib.h& ...
- PAT Advanced A1021 Deepest Root (25) [图的遍历,DFS,计算连通分量的个数,BFS,并查集]
题目 A graph which is connected and acyclic can be considered a tree. The height of the tree depends o ...
- PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]
题目 One way that the police finds the head of a gang is to check people's phone calls. If there is a ...
随机推荐
- 记微信开发(自定义回复&关注回复)
记微信开发(自定义回复&关注回复) 记微信开发(自定义回复&关注回复) code: <?php/** * wechat php test *///define your toke ...
- 浅谈AngularJS启动引导过程
我们都知道AngularJS默认会执行app.js来启动整个angular项目,但你知道angular具体执行过程吗? 一.自动引导启动框架 例如我们有如下代码,我们想要完成一个指令功能: <h ...
- python运维开发(八)----面向对象(下)
内容目录: 面向对象三大特性之多态性 面向对象中的成员:字段.方法.属性 类的成员修饰符 类的特殊成员 特殊成员方法 面向对象其他 异常处理 设计模式之单例模式 面向对象的多态性 多态性:即指多种形态 ...
- 1206: B.求和
题目描述 点击这里 对于正整数n,k,我们定义这样一个函数f,它满足如下规律 现在给出n和k,你的任务就是要计算f(n,k)的值. 输入 首先是一个整数T,表示有T组数据 接下来每组数据是n和k(1& ...
- linux function
#!/bin/bash function sayHello() { #这里的{ 和它前面的)之间可以没有空格 echo "Hello $1" } sayHello 'Neeky'
- Nginx 变量漫谈(一)
Nginx 的配置文件使用的就是一门微型的编程语言,许多真实世界里的 Nginx 配置文件其实就是一个一个的小程序.当然,是不是“图灵完全的”暂且不论,至少据我观察,它在设计上受 Perl 和 Bou ...
- python学习day8
目录 一.异常 二.多线程 三.守护线程与join 四.GIL与多线程锁 五.递归锁与信号量 六.线程间同步与交互 七.多进程 八.进程间通信与数据共享 九.进程池 一.异常 1.异常处理 在编程过程 ...
- Qt-4.6动画Animation快速入门三字决
Qt-4.6动画Animation快速入门三字决 Qt-4.6新增了Animation Framework(动画框架),让我们能够方便的写一些生动的程序.不必像以前的版本一样,所有的控件都枯燥的呆在伟 ...
- 跨域(cross-domain)访问 cookie (读取和设置)
Passport 一方面意味着用一个帐号可以在不同服务里登录,另一方面就是在一个服务里面登录后可以无障碍的漫游到其他服务里面去.坦白说,目前 sohu passport 在这一点实现的很烂(不过俺的工 ...
- CodeForces - 527D Clique Problem (图,贪心)
Description The clique problem is one of the most well-known NP-complete problems. Under some simpli ...