图论算法-建图和最短路

来源:互联网 发布:黑帽seo劫持博客违法吗 编辑:程序博客网 时间:2024/06/18 11:13

建图方法:

详细参见http://blog.csdn.net/stay_accept/article/details/50886067

常见两种:

链接表法

#include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <iostream>  #include <algorithm>  using namespace std;  int N,M;  struct node{      int to,w;      node *next;  };  struct edge{      node *first;  }G[105];  //存第一条边int main(){      int i,j,x,y,z;      scanf("%d%d",&N,&M);      for(i=0;i<M;i++){          scanf("%d%d%d",&x,&y,&z);          node *p=new node;          p->to=y;          p->w=z;          p->next=G[x].first;                     //每条边连在当前节点的前一条边上          G[x].first=p;                           //形成一个链式储存结构,first为当前节点的最后      }                                           //一条边      node *k;      for(i=1;i<=N;i++){                          //图的遍历          for(k=G[i].first;k!=NULL;k=k->next)               printf("%d %d %d\n",i,k->to,k->w);      }      return 0;  }  


vector 建图(以网络流建图为例)

struct Node{int to;//终点  int cap;//容量int flow=0;int rev; //反向点int cost; //费用};typedef vector<Node>* Graph;void add_Node(Graph v,int from, int to, int cap,int cost)  //加边  {Node nodefrom,nodeto;nodefrom.to = to, nodefrom.cap =cap,nodefrom.rev = v[to].size(),nodefrom.cost = cost;v[from].push_back(nodefrom);nodeto.to = from, nodeto.cap =cap, nodeto.rev = v[from].size()-1,nodeto.cost =cost;v[to].push_back(nodeto);}


最短路算法Dijkstra

//Dijkstra求单源最短路径  void Dijkstra(Graph G,int Vcount,int s,int path[],int dist[]){      //Vcount:顶点个数;s:开始结点;path[]用于返回由开始结点到相应结点的路径指示      int i,j,w,minc,dist[Vcount],mark[Vcount];  //mark记录是否访问过    memset(mark,0,Vcount); //开始都没有访问过     for(i=0;i<Vcount;i++){          dist[i]=G[s][i];          path[i]=s;      }     //初始化,不可达的话设置为无穷    mark[s]=1;path[s]=0;dist[s]=0;      for(i=1;i<Vcount;i++){          minc=INFINITY;          w=0;          for(j=0;j<Vcount;j++)              if(!mark[j] && minc>=dist[j]){                  minc=dist[j];                  w=j;  //找出目前到达最小的边            }          mark[w]=1;  //访问        for(j=0;j<Vcount;j++)              if(!mark[j] && G[w][j]!=INFINITY && dist[j]>dist[w]+G[w][j]){                  dist[j]=dist[w]+G[w][j];                  path[j]=w;  //可松弛更新            }      }  }  //注意:输入的图的边的权值必须非负(这是Dijkstra的局限性所在).  
floyd算法

void Floyd_Warshall(Graph G,int Vcount,Graph D,Graph P){        //D:D[i][j]表示从i到j的最短距离;P:P[i][j]表示从i到j的最短路径上的结点      int i,j,k;      for(i=0;i<Vcount;i++)          for(j=0;j<Vcount;j++){              D[i][j]=G[i][j];              P[i][j]=i;          }  //用这个算法最好用矩阵建图,初始化    for(i=0;i<Vcount;i++){          D[i][i]=0;          P[i][i]=0;      }  //注意对角线初始化0    for(k=0;k<Vcount;k++)          for(i=0;i<Vcount;i++)              for(j=0;j<Vcount;j++)                  if(D[i][j]>D[i][k]+D[k][j]){                      D[i][j]=D[i][k]+D[k][j];                      P[i][j]=P[k][j];                  }  //比较所有i经过点k然后再到j的距离}  


bellmanford 算法

bool BellmanFord( int s )  {      for( int i = 0; i < n; i ++ )          dis[i] = inf;      dis[s] = 0;      for( int i = 0; i < n-1; i ++ )  //n-1次松弛      {          for( int j = 0; j < n; j ++ ) //每一次对所有边操作         {              if( dis[j] == inf )                  continue;              for( int k = 0; k < map[j].size(); k ++ )              {                  node u = map[j][k];                  if( u.w != inf && dis[u.id] > dis[j] + u.w )                      dis[u.id] = dis[j] + u.w;              }          }      }      for( int j = 0; j < n; j ++ )      {          if( dis[j] == inf )              continue;          for( int k = 0; k < map[j].size(); k ++ )          {              node u = map[j][k];              if( u.w != inf && dis[u.id] > dis[j] + u.w )                  return false;          }      }  //检查负值圈    return true;  }  

SPFA 算法(bellman优化)

void SPFA(int v0)  {      memset(vis, false, sizeof(vis));      for(int i = 1; i <= n; i++)          dis[i] = INF;      dis[v0] = 0;      queue <int> q;      q.push(v0);      while(!q.empty())      {          int u = q.front();          q.pop();          vis[u] = false;          int sz = vt[u].size();          for(int i = 0; i < sz; i++)          {              int v = vt[u][i].v;              int w = vt[u][i].w;              if(dis[v] > dis[u] + w)              {                  dis[v] = dis[u] + w;                  if(!vis[v])                  {                      q.push(v);                      vis[v] = true;                  }              }          }      }  }  









0 0
原创粉丝点击