现在的位置: 首页 > 综合 > 正文

图论模版

2019年02月24日 ⁄ 综合 ⁄ 共 3334字 ⁄ 字号 评论关闭

Dijkstra+邻接表(HDU 2544 最短路)

#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
#define  pret(a,b)  memset(a,b,sizeof(a))
const int INF = 99999999 ;
const int MX= 20005 ;
int n,m,top ;
bool vis[MX] ;
int d[MX] ;
struct vertx // 与要查找顶点相关的第一个边序号
{
    int head ;
}V[MX] ;
struct Edge 
{
    int v,w ;
    int next ; //下标和内容均为边序号
}E[MX] ;
void add_edge(int u,int v,int w) // 无向图
{
    E[top].v=v ;
    E[top].w=w ;
    E[top].next=V[u].head ;
    V[u].head=top++ ;
    E[top].v=u ;
    E[top].w=w ;
    E[top].next=V[v].head ;
    V[v].head=top++ ;
}
void init() // 初始化
{
    pret(vis,false) ;
    pret(V,-1) ;
    top=0 ;
}
void Dijkstra()
{
    for(int i=0 ;i<n ;i++)
           d[i]=INF ;
    d[0]=0 ;
    for(int i=0 ;i<n ;i++)
    {
        int min=INF,sx ;
        for(int j=0 ;j<n ;j++)
           if(!vis[j]&&d[j]<min)
               min=d[sx=j] ;
        if(min==INF)  break ;
        vis[sx]=true ;
        for(int j=V[sx].head ;j!=-1 ;j=E[j].next)
        {
            int sy=E[j].v ;
            if(!vis[sy]&&d[sx]+E[j].w<d[sy])
              d[sy]=d[sx]+E[j].w ;
        }
    }
}
int main()
{
    int u,v,w ;
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        init() ;
        for(int i=0 ;i<m ;i++)
        {
            scanf("%d%d%d",&u,&v,&w) ;
            u-- ; v-- ; // 下标从零开始
            add_edge(u,v,w) ;
        }
        Dijkstra() ;
        printf("%d\n",d[n-1]) ;
    }
    return 0 ;
}

Dijstra + 邻接表 + 优先队列

#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
#define  pret(a,b)  memset(a,b,sizeof(a))
const int INF = 99999999 ;
const int MX= 20005 ;
int n,m,top ;
bool vis[MX] ;
int d[MX] ;
struct node
{
    int x,w ;
    friend bool operator < (const node &a,const node &b)
    {
        return a.w > b.w ;
    }
} ;
struct vertx // 与要查找顶点相关的第一个边序号
{
    int head ;
}V[MX] ;
struct Edge
{
    int v,w ;
    int next ; //下标和内容均为边序号
}E[MX] ;
void add_edge(int u,int v,int w) // 无向图
{
    E[top].v=v ;
    E[top].w=w ;
    E[top].next=V[u].head ;
    V[u].head=top++ ;
    E[top].v=u ;
    E[top].w=w ;
    E[top].next=V[v].head ;
    V[v].head=top++ ;
}
void init() // 初始化
{
    pret(vis,false) ;
    pret(V,-1) ;
    top=0 ;
}
void Dijkstra()
{
    priority_queue<node>Q ;
    for(int i=0 ;i<n ;i++)
           d[i]=INF ;
    d[0]=0 ;
    node curt ;
    curt.x=0 ;curt.w=0 ;
    Q.push(curt) ;
    while(!Q.empty())
    {
        curt=Q.top() ;
        Q.pop() ;
        int sx=curt.x ;
        if(vis[sx])  continue ; // 标记顶点
        vis[sx]=true ;
        for(int e=V[sx].head ; e!=-1 ;e=E[e].next) // 更新
        {
            int sy=E[e].v ;
            if(d[sx]+E[e].w<d[sy])
            {
                d[sy]=d[sx]+E[e].w ;
                curt.x=sy ;
                curt.w=d[sy] ;
                Q.push(curt) ;
            }
        }
    }
}
int main()
{
    int u,v,w ;
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        init() ;
        for(int i=0 ;i<m ;i++)
        {
            scanf("%d%d%d",&u,&v,&w) ;
            u-- ; v-- ; // 下标从零开始
            add_edge(u,v,w) ;
        }
        Dijkstra() ;
        printf("%d\n",d[n-1]) ;
    }
    return 0 ;
}

Spfa ( HDU 1874 畅通工程续 ) (别忘了在主函数里调用 init( ) 函数!!!)

#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
#define  pret(a,b)  memset(a,b,sizeof(a))
const int INF = 99999999 ;
const int MX= 20005 ;
int n,m,top ;
bool vis[MX] ;
int d[MX] ;
struct vertx
{
    int head ;
}V[MX] ;
struct Edge
{
    int v,w ;
    int next ;
}E[MX] ;
void init()
{
    pret(vis,false) ;
    pret(V,-1) ;
    for(int i=0 ;i<n ;i++)
       d[i]=INF ;
    top=0 ;
}
void add_edge(int u,int v,int w)
{
    E[top].v=v ;
    E[top].w=w ;
    E[top].next=V[u].head ;
    V[u].head=top++ ;
    E[top].v=u ;
    E[top].w=w ;
    E[top].next=V[v].head ;
    V[v].head=top++ ;
}
void Spfa(int s)
{
    queue<int>q ;
    vis[s]=true ;
    d[s]=0 ;
    q.push(s) ;
    while(!q.empty())
    {
        int x=q.front() ;
        q.pop() ;
        vis[x]=false ;
        for(int i=V[x].head ;i!=-1 ;i=E[i].next)
        {
            int p=E[i].v ;
            if(d[x]+E[i].w<d[p])
            {
                d[p]=d[x]+E[i].w ;
                if(!vis[p])
                {
//判断环放在这里面      vis[p]=true ;
                     q.push(p) ;
                }
            }
        }
    }
}
int main()
{
    int u,v,w,x,y ;
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        init() ;
        for(int i=0 ;i<m ;i++)
        {
            scanf("%d%d%d",&u,&v,&w) ;
            add_edge(u,v,w) ;
        }
        scanf("%d%d",&x,&y) ;
        Spfa(x) ;
        printf("%d\n",d[y]==INF ? -1 : d[y]) ;
    }
    return 0 ;
}

 

【上篇】
【下篇】

抱歉!评论已关闭.