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;
}