0412备战蓝桥杯,图论复习

1.朴素dijkstra

cpp 复制代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>

using namespace std;
const int N = 510; 

int n,m;
int g[N][N],dist[N];
bool st[N];

int dij(){
	
	memset(dist,0x3f,sizeof dist);
	dist[1] = 0;
	
	for(int i=0;i<n;i++){//n次迭代 
		int t = -1;
		for(int j=1;j<=n;j++)
			if(!st[j] && (t == -1 || dist[j] < dist[t])) 
				t=j;
		st[t] = true;
		for(int j=1;j<=n;j++){
			dist[j] = min(dist[j],dist[t]+g[t][j]);
		} 
	}
	
	if(dist[n] == 0x3f3f3f3f) return -1;
	return dist[n];
}
int main()
{
	cin>>n>>m;
	memset(g,0x3f,sizeof g);
	
	for(int i=0;i<m;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		g[a][b] = min(g[a][b],c);
	}
	
	int t = dij();
	cout<<t<<endl;
	return 0;
}

2.floyd:初始化自己到自己是0

cpp 复制代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>

using namespace std;
const int N = 210; 

int n,m,k;
int e[N][N];
int st[N];

void floyd(){
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				e[i][j] = min(e[i][j],e[i][k]+e[k][j]);
			}
		}
	}
	return ;
}


int main(){
	cin>>n>>m>>k;
	//memset(e,0x3f,sizeof e);
	for(int i=1;i<=n;i++){
	    for(int j=1;j<=n;j++){
	        if(i==j) e[i][j] = 0;
	        else e[i][j] = 0x3f3f3f3f;
	    }
	}
	while(m--){
		int a,b,c;
		cin>>a>>b>>c;
		e[a][b] = min(e[a][b],c);
	}
	
	floyd();
	
	while(k--){
		int x,y;
		cin>>x>>y;
		
		if(e[x][y] > 0x3f3f3f3f/2) cout<<"impossible"<<endl;
		else cout<<e[x][y]<<endl;
	}
	return 0;
} 

3.prim:点到集合的距离

cpp 复制代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>

using namespace std;
const int N = 510; 

int e[N][N];
int st[N];
int dist[N];//点到集合的距离 
int n,m;
int res;
int cnt;

int prim(){
	memset(dist,0x3f,sizeof dist);
	
	for(int i=0;i<n;i++)//n次迭代
	{
		int t=-1;
		for(int j=1;j<=n;j++){
			if(!st[j] && (t==-1 || dist[j]<dist[t])){
				t=j;
			}
		}
		if(i && dist[t] == 0x3f3f3f3f){
			return 0x3f3f3f3f;//一定要返回无穷大1,不然-1也有可能是答案
		}
		if(i) res+=dist[t];
		st[t] = true;

	/*	st[t] = true;
		cnt++;
		res+=dist[t];
		*/
		for(int j=1;j<=n;j++){
			//用t更新点到集合的距离
			dist[j] = min(dist[j], e[t][j]); 
		}
		
	} 

	return res;
}
int main()
{
	cin>>n>>m;
	memset(e,0x3f,sizeof e);
	while(m--){
		int u,v,w;
		cin>>u>>v>>w;
		if(u==v) continue;
		e[u][v] = e[v][u] = min(e[v][u],w);
	}	
	
	if(prim() == 0x3f3f3f3f) cout<<"impossible"<<endl;
	else cout<<prim()<<endl;
	return 0;
} 
 

4.kruskal:选取最小边进入集合,注意并查集p[x] = find(p[x])

cpp 复制代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>

using namespace std;
const int N = 200010; 
//kruskal从最短边加入集合
int p[N];
int n,m;
struct node{
	int u,v,w;
}; 
node e[N];
int res,cnt;

bool cmp(node aa,node bb){
	return aa.w < bb.w;
}

int find(int x){
	if(p[x] != x) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) p[i]=i;
	
	for(int i=1;i<=m;i++)
	{
		int u,v,w;
	//	if(u==v) continue;
		cin>>u>>v>>w;
		e[i] = {u,v,w};
	}	
	sort(e+1,e+m+1,cmp);
	//枚举每条边 
	for(int i=1;i<=m;i++){
		int u=e[i].u;
		int v=e[i].v;
		int w=e[i].w;
		u=find(u);
		v=find(v);
		if(u!=v){
			//如果不在一个连通块
			res += w;
			cnt++;
			p[u] = v;//加入集合 
		} 
	}
	if(cnt<n-1) cout<<"impossible"<<endl;
	else cout<<res<<endl; 
	return 0;
} 
相关推荐
VT.馒头2 分钟前
【力扣】2727. 判断对象是否为空
javascript·数据结构·算法·leetcode·职场和发展
goodluckyaa11 分钟前
LCR 006. 两数之和 II - 输入有序数组
算法
孤狼warrior12 分钟前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
Σίσυφος190037 分钟前
PCL法向量估计 之 RANSAC 平面估计法向量
算法·机器学习·平面
xhbaitxl42 分钟前
算法学习day39-动态规划
学习·算法·动态规划
I_LPL43 分钟前
day23 代码随想录算法训练营 回溯专题2
算法·hot100·回溯算法·求职面试
智者知已应修善业1 小时前
【洛谷P9975奶牛被病毒传染最少数量推导,导出多样例】2025-2-26
c语言·c++·经验分享·笔记·算法·推荐算法
Trouvaille ~1 小时前
【Linux】应用层协议设计实战(一):自定义协议与网络计算器
linux·运维·服务器·网络·c++·http·应用层协议
CSCN新手听安1 小时前
【linux】高级IO,I/O多路转接之poll,接口和原理讲解,poll版本的TCP服务器
linux·运维·服务器·c++·计算机网络·高级io·poll
CSCN新手听安1 小时前
【linux】网络基础(三)TCP服务端网络版本计算器的优化,Json的使用,服务器守护进程化daemon,重谈OSI七层模型
linux·服务器·网络·c++·tcp/ip·json