建图方法:
详细参见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;
}
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;
}
}
}
}
}