算法模板 图的基本操作

图的最短路径

迪杰斯特拉算法(解决单源最短路径)

#include 
#include
#include
#include 
#include
typedef long long ll;
using namespace std;
#define maxn 2510
bool inqueen[3001];
struct Edge{
    int v,cost;
};
ll dis[3001],inf=ll(1e18);
vector<Edge> edge[maxn];
int main()
{
    int n,m,s,t,u,v,w;
    scanf("%d %d %d %d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&u,&v,&w);
        edge[u].push_back({v,w});
        edge[v].push_back({u,w});
    }
    queue<int>Q;
    for(int i=1;i<=n;i++)
    {
      dis[i]=inf;
    }
    memset(inqueen,false,sizeof(inqueen));
 dis[s]=0;
    Q.push(s);
    inqueen[s]=true;
    while(!Q.empty()){
        int b=Q.front();
        Q.pop();
        //printf("%d\n",b);
        inqueen[b]=false;
        int size=int(edge[b].size());
        for(int i=0;i<size;i++)
        {
            int v=edge[b][i].v,cost=edge[b][i].cost;
            if(dis[v]>dis[b]+cost){
                dis[v]=dis[b]+cost;
              if(!inqueen[v]){
                    Q.push(v);
                    inqueen[v]=true;
                }
            }
        }
    }
    printf("%lld\n",dis[t]);
    return 0;
}

flody

#include
#include
#include
#include
#include
#include
using namespace std;
int n;
#define maxn 0x1f3f3f3f
int map[201][201];
int main()
{
 int n,m,t;
 scanf("%d",&t);
 while(t--)
 {
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)
  {
   for(int j=1;j<=n;j++)
   {
    if(i==j) map[i][j]=0;
    else map[i][j]=maxn;
   }
  }
  while(m--)
  {
   int u,v,c;
   scanf("%d%d%d",&u,&v,&c);
   map[u][v]=c;
  }
  int i,j,k,maxpath=-2;
  for(k=1;k<=n;k++)
  {
   for(i=1;i<=n;i++)
   { 
    for(int j=1;j<=n;j++)
     map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
   }
  }
  for(i=1;i<=n;i++)
   for(j=1;j<=n;j++)
   {
    if(map[i][j]!=maxn&&i!=j)
     maxpath=max(maxpath,map[i][j]);
   }
  for(int i=1;i<=n;i++)
  {
   for(int j=1;j<=n;j++)
   {
    if(map[i][j]==maxpath)
     printf("%d %d\n",i,j);
   }
  }
 }
 } 

图的遍历

bfs和dfs 邻接表形式

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int ms = 1e5 + 5;
vector<int> g[ms];
queue<int> q;
int n, m; 
bool vis[ms];//g数组代表一个二维数组,d代表一个入度,vis代表是否访问 
 void bfs()
 {
  while(!q.empty())
  {
   int u=q.front();
   q.pop();
   for(int i:g[u])
   {
   if(!vis[i])
   {
    q.push(i);
    printf("%d ",i);
    vis[i]=true;
   }   
  }
 }
 }
 void dfs(int t)
 {
  vis[t]=true;
  printf("%d ",t);
  for(int i:g[t])
  {
   if(!vis[i])
    dfs(i);
  }
 }
 int main()
 {
  int n,m,a,b;
  scanf("%d%d",&n,&m);
  while(m--)
  {
   scanf("%d%d",&a,&b);
   g[a].push_back(b);
 }
 for(int i=1;i<=n;i++)
 {
  if(!vis[i])
  {
   q.push(i);
    vis[i]=true;
    printf("%d ",i);
    bfs();
  }
 }
 printf("\n");
 for(int i=1;i<=n;i++)
 {
  if(!vis[i])
   dfs(i);
 }
 }

邻接有权表BFS遍历

#include 
#include
#include
#include 
#include
typedef long long ll;
using namespace std;
#define maxn 2510
bool inqueen[3001];
struct Edge{
    int v,cost;
};
ll dis[3001],inf=ll(1e18);
vector<Edge> edge[maxn];
int main()
{
    int n,m,s,t,u,v,w;
    scanf("%d %d %d %d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&u,&v,&w);
        edge[u].push_back({v,w});
        edge[v].push_back({u,w});
    }
    queue<int>Q;
    for(int i=1;i<=n;i++)
    {
      dis[i]=inf;
    }
    memset(inqueen,false,sizeof(inqueen));
 dis[s]=0;
    Q.push(s);
    inqueen[s]=true;
    while(!Q.empty()){
        int b=Q.front();
        Q.pop();
        //printf("%d\n",b);
        inqueen[b]=false;
        int size=int(edge[b].size());
        for(int i=0;i<size;i++)
        {
            int v=edge[b][i].v,cost=edge[b][i].cost;
            if(dis[v]>dis[b]+cost){
                dis[v]=dis[b]+cost;
              if(!inqueen[v]){
                    Q.push(v);
                    inqueen[v]=true;
                }
            }
        }
    }
    printf("%lld\n",dis[t]);
    return 0;
}

你可能感兴趣的:(算法模板 图的基本操作)