图论模版

来源:互联网 发布:excel拆分数据公式 编辑:程序博客网 时间:2024/05/23 16:59

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



 

0 0