图论模板

         图论基础模板

Dijkstra

算法分析:

  按路径长度递增次序产生算法:
  把顶点集合V分成两组:
  (1)S:已求出的顶点的集合(初始时只含有源点V0)
  (2)V-S=T:尚未确定的顶点集合
  将T中顶点按递增的次序加入到S中,保证:
  (1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度
  (2)每个顶点对应一个距离值
     S中顶点:从V0到此顶点的长度。
     T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度。
     依据:V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和。

 

#include<bits/stdc++.h>
#define N 100000
using namespace std;
int a[N],f[N];
int n,m,ff,tt,cut;
int h[N],ne[N],t[N],v[N];
void add(int f,int to,int vis){ne[++cut]=h[f],h[f]=cut,t[cut]=to,v[cut]=vis;}
priority_queue<pair<int ,int >,vector<pair<int,int > >,greater<pair<int ,int > > >dl;
void dij(int x)
{
    dl.push(make_pair(0,x));
    a[x]=0;
    while(dl.size())
    {
        x=dl.top().second;dl.pop();
        if(x==tt){cout<<a[tt];return;}
        if(f[x])continue;f[x]=1;
        for(int i=h[x];i;i=ne[i])
        {
            int y=t[i];
            if(a[x]+v[i]<a[y]){a[y]=a[x]+v[i];dl.push(make_pair(a[y],y));}
        }
    }
}
int main()
{
    cin>>n>>m>>ff>>tt;
    memset(a,0x3f3f3f3f,sizeof(a));
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
    }
    dij(ff);
    return 0;
}

 

 

 

SPFA

 

LCA

 

 fa[][]->f[][];

#include<bits/stdc++.h>
#define N 500010
#define M 31
using namespace std;
int f[N][M],lg[N],dept[N];
int head[N],to[N],net[N],cut;
void add(int from,int t)
{
    net[++cut]=head[from];
    to[cut]=t;
    head[from]=cut;
}
void dfs(int fa,int x)
{
    f[x][0]=fa;
    dept[x]=dept[fa]+1;
    for(int i=1;i<=lg[dept[x]];i++)
        f[x][i]=f[f[fa][i-1]][i-1];
    for(int i=head[x];i;i=net[i])
        if(to[i]!=fa)dfs(x,to[i]);
}
int lca(int x,int y)
{
    if(x<y)swap(x,y);
    while(dept[x] > dept[y])
        x = f[x][lg[dept[x]-dept[y]] - 1];
    if(x==y)return x;
    for(int i=lg[dept[x]]-1;i>=0;i--)
        if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    return f[x][0];
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        lg[i] = lg[i-1] + (1 << lg[i-1] == i);    
    for(int i=1;i<n;i++)
    {

        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs(0,1);
    int k;
    cin>>k;
    for(int i=1;i<=k;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}

 



 

posted @ 2021-01-05 13:21  君与  阅读(60)  评论(0编辑  收藏  举报