C++模板 单源最短路 多源最短路 最小生成树

dijkstra1

正边权,稠密图,邻接矩阵

void dijkstra(int u) 
{
	memset(dist,0x3f,sizeof dist);
	dist[u]=0;
	for(int i=0;i<n;++i)
	{
		int t=-1;
		for(int j=0;j<n;++j)//根据编号从0开始 
		{
			if(st[j]==false&&(t==-1||dist[j]<dist[t]))t=j;
		}
		st[t]=true;
		for(int j=0;j<n;++j)
		{
			if(st[j])continue;
			if(dist[j]>dist[t]+g[t][j]){
				dist[j]=dist[t]+g[t][j];
			}
		}
	}
}

不可达条件:dist[n]==INF
邻接矩阵的初始化:
memset(g,0x3f,sizeof g)
for(int i=0;i<n;++i)g[i][i]=0;
dijkstra2

正边权,稀疏图,邻接表

void dijkstra(int u)
{
	priority_queue<node> q;
	dist[u]=0;
	q.push(node(u,0));
	while(!q.empty())
	{
		node t=q.top();q.pop();
		if(st[t.id])continue;
		st[t.id]=true;
		for(int i=h[t.id];i!=-1;i=ne[i])
		{
			int j=e[i];
			if(st[j])continue;
			if(dist[j]>dist[t.id]+w[i]){
				dist[j]=dist[t.id]+w[i];
				q.push(node(j,dist[j]));
			}
		}
	}
} 
不可达条件:dist[n]==INF

node 重载<

class node
{
	public :
		ll id,w;
		node(){
		}
		node(ll a,ll b){
			id=a;w=b;
		}
		bool operator <(const node & b) const 
		{
			return w>b.w;
		}
};

spfa

负边权 稀疏图 邻接表
限制:不存在负环

void spfa(int u)
{
	memset(dist,0x3f,sizeof dist);
	dist[u]=0;
	queue<int> q;
	q.push(u);
	st[u]=true;
	while(!q.empty())
	{
		int t=q.front();q.pop();
		st[t]=false;
		for(int i=h[t];i!=-1;i=ne[i])
		{
			int j=e[i];
			if(dist[j]>dist[t]+w[i])
			{
				dist[j]=dist[t]+w[i];
				if(st[j]==false)
				{
					q.push(j);
					st[j]=true;
				}
			}
		}
	}
}

不可达条件:dist[n]>INF/2 
spfa判断负环

无源点

bool spfa()
{
	memset(dist,0x3f,sizeof dist);
	queue<int> q;
	for(int i=1;i<=n;++i)
	{
		st[i]=true;
		q.push(i);
	}
	while(!q.empty())
	{
		int t=q.front();q.pop();
		st[t]=false;
		for(int i=h[t];i!=-1;i=ne[i])
		{
			int j=e[i];
			if(dist[j]>dist[t]+w[i])
			{
				dist[j]=dist[t]+w[i];
				cnt[j]=cnt[t]+1;
				if(cnt[j]==n)return true;
				if(st[j]==false)
				{
					q.push(j);
					st[j]=true;
				}
			}
		}
	}
	return false;
}
floyd

多源最短路
负边权 只适用于稠密图n在500以内 可以不存图,直接放入dist数组

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

不可达条件:dist[i][j]>INF/2 

初始化

memset(dist,0x3f,sizeof dist);
	for(int i=1;i<=n;++i)dist[i][i]=0;//不可以漏掉这一行
	while(m--)
	{
		int x,y,z;cin>>x>>y>>z;
		dist[x][y]=min(dist[x][y],z);
		dist[y][x]=dist[x][y];
	}
prim

最小生成树
稠密图,邻接矩阵

int prim(int u)
{
	memset(dist,0x3f,sizeof dist);
	int res=0;
	for(int i=0;i<n;++i)
	{
		int t=-1;
		for(int j=1;j<=n;++j)
		{
			if(st[j]==false &&(t==-1||dist[j]<dist[t]))t=j;
		}
		st[t]=true;
		if(i!=0&&dist[t]==INF)return INF;
		if(i!=0)res+=dist[t];
		for(int j=1;j<=n;++j)dist[j]=min(dist[j],g[t][j]);
	}
	return res;
} 
posted @ 2022-11-17 23:02  林动  阅读(14)  评论(0编辑  收藏  举报