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;
} 
相关推荐
超的小宝贝13 分钟前
数据结构算法(C语言)
c语言·数据结构·算法
凤年徐2 小时前
【数据结构初阶】单链表
c语言·开发语言·数据结构·c++·经验分享·笔记·链表
oioihoii2 小时前
C++11 右值引用:从入门到精通
开发语言·c++
木子.李3476 小时前
排序算法总结(C++)
c++·算法·排序算法
闪电麦坤957 小时前
数据结构:递归的种类(Types of Recursion)
数据结构·算法
freyazzr7 小时前
C++八股 | Day2 | atom/函数指针/指针函数/struct、Class/静态局部变量、局部变量、全局变量/强制类型转换
c++
Gyoku Mint8 小时前
机器学习×第二卷:概念下篇——她不再只是模仿,而是开始决定怎么靠近你
人工智能·python·算法·机器学习·pandas·ai编程·matplotlib
纪元A梦8 小时前
分布式拜占庭容错算法——PBFT算法深度解析
java·分布式·算法
fpcc8 小时前
跟我学c++中级篇——理解类型推导和C++不同版本的支持
开发语言·c++
px不是xp8 小时前
山东大学算法设计与分析复习笔记
笔记·算法·贪心算法·动态规划·图搜索算法