图的基本算法
Posted Ja_King_ZH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的基本算法相关的知识,希望对你有一定的参考价值。
bellman-ford算法(有边数限制时使用)
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510,M=10010;
int dist[N],backup[N];
int n,m,k;
struct edge
int a,b,w;
edges[M];
int bellman_ford()
memset(dist,0x3f,sizeof(dist));
dist[1]=0;
for(int i=0;i<k;i++)
memcpy(backup,dist,sizeof dist);
for(int j=1;j<=m;j++)
int a=edges[j-1].a,b=edges[j-1].b,w=edges[j-1].w;
dist[b]=min(dist[b],backup[a]+w);
//if(dist[n]>0x3f3f3f3f/2)return -1;
return dist[n];
int main()
cin>>n>>m>>k;
for(int i=0;i<m;i++)
int a,b,w;
cin>>a>>b>>w;
edges[i]=a,b,w;
int t=bellman_ford();
if(t>0x3f3f3f3f/2)puts("impossible");
else cout<<t;
return 0;
dijkstra算法
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=510;
int g[N][N]; //为稠密阵所以用邻接矩阵存储
int dist[N]; //用于记录每一个点距离第一个点的距离
bool st[N]; //用于记录该点的最短距离是否已经确定
int n,m;
int Dijkstra()
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++)
int t=-1;
for(int j=1;j<=n;j++)
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
st[t]=true;
for(int u=1;u<=n;u++)
dist[u]=min(dist[u],dist[t]+g[t][u]);
if(dist[n]==0x3f3f3f3f)return -1;
return dist[n];
int main()
cin>>n>>m;
memset(g,0x3f,sizeof g); //初始化图 因为是求最短路径
//所以每个点初始为无限大
while(m--)
int x,y,z;
cin>>x>>y>>z;
g[x][y]=min(g[x][y],z); //如果发生重边的情况则保留最短的一条边
cout<<Dijkstra()<<endl;
return 0;
Floyd算法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=210;
int g[N][N];
int m,n,k;
int main()
cin>>n>>m>>k;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(i==j)g[i][j]=0;
else g[i][j]=999999;
for(int i=0;i<m;i++)
int a,b,c;
cin>>a>>b>>c;
g[a][b]=min(g[a][b],c);
for(int v=1;v<=n;v++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(g[i][j]>g[i][v]+g[v][j])
g[i][j]=g[i][v]+g[v][j];
while(k--)
int x,y;
cin>>x>>y;
if(g[x][y]>= 900000)printf("impossible\\n");
else cout<<g[x][y]<<endl;
return 0;
spfa算法
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e5+10;
int e[N],ne[N],h[N],w[N],idx;
int n, m;
int dist[N];
bool st[N];
void add(int a,int b,int c)
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
int spfa()
memset(dist,0x3f,sizeof dist);
dist[1]=0;
queue<int>q;
q.push(1);
st[1]=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])
q.push(j);
st[j]=true;
//if(dist[n]==0x3f3f3f3f)return -1;
return dist[n];
int main()
memset(h,-1,sizeof(h));
cin>>n>>m;
for(int i=0;i<m;i++)
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
int t=spfa();
if(t==0x3f3f3f3f)puts("impossible");
else cout<<t;
return 0;
prim算法(最小生成树)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=510;
int n,m;
int g[N][N],dist[N];
bool st[N];
int prim()
memset(dist,0x3f,sizeof dist);
int ans=0;
for(int i=1;i<=n;i++)
int t=-1;
for(int j=1;j<=n;j++)
if(!st[j]&&(t==-1||dist[j]<dist[t]))
t=j;
st[t]=true;
if((i-1)&&dist[t]==0x3f3f3f3f)return 0x3f3f3f3f;
if(i-1) ans+=dist[t];
for(int v=1;v<=n;v++)
dist[v]=min(dist[v],g[t][v]);
return ans;
int main()
memset(g,0x3f,sizeof g);
cin >> n >> m;
while(m--)
int a,b,c;
cin>>a>>b>>c;
g[a][b]=g[b][a]=min(g[a][b],c);
int t=prim();
if(t==0x3f3f3f3f)cout<<"impossible";
else cout<<t;
return 0;
拓扑排序
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
int e[N],ne[N],h[N],idx;
int n,m;
int q[N],d[N];
void add(int a,int b)
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
bool topsort()
int hh=0,tt=-1;
for(int i=1;i<=n;i++)
if(d[i]==0)q[++tt]=i;
while(hh<=tt)
int t=q[hh++];
for(int i=h[t];i!=-1;i=ne[i])
int j=e[i];
d[j]--;
if(d[j]==0) q[++tt]=j;
return tt==n-1;
int main()
memset(h,-1,sizeof h);
cin>>n>>m;
for(int i=0;i<m;i++)
int a,b;
cin>>a>>b;
add(a,b);
d[b]++;
if(topsort())
for(int i=0;i<n;i++)
cout<<q[i]<<' ';
else
cout<<-1;
return 0;
图的dfs和bfs
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<queue>
#include<stdio.h>
using namespace std;
//dfs求岛屿面积
const int N = 1100;
int arr[N][N], book[N][N], sum = 1, m, n, x, y;
void dfs(int x, int y)
int dx[4] = 1,0,-1,0 ;
int dy[4] = 0,1,0,-1 ;
int ddx, ddy;
for (int i = 0;i < 4;i++)
ddx = x + dx[i];
ddy = y + dy[i];
if (ddx > m || ddx<1 || ddy>n || ddy < 1)
continue;
if (arr[ddx]图的基本算法