1.单元单点最短路径问题
最简单的遍历从源节点S开始,相邻结点有很多,
1.1 深度优先与广度优先
深度优先搜索是一直往前走,只要前面有路,走到没有路为止
广度优先一源点为圆心画一个越来愈大的圆
dijkstra算法:不能处理负权值(效率不错)
//复习dijstra算法 不能判断负权值 #include<iostream> #include<cstring> using namespace std; const int M=0x7fffffff; int a[1500][1500]; //存两点之间的距离 int dis[1500];//存点到目标点的距离 int book[1500];//标记已经访问的点 int m,n; //m表示点个数 void dijstra(int m){ int flag,u; memset(book,0,sizeof(book)); // for(int i=1;i<m;i++) cout<<book[i]<<endl; // cout<<"hello"<<endl;//2 for(int i=0;i<m;i++) dis[i]=a[0][i]; book[0]=1; for(int i=0;i<m-1;i++){ //表示有n-1次比较 flag=M; for(int j=1;j<m;j++){//寻找没访问的剩下的离0最近的点 if(book[j]==0&&dis[j]<flag){ flag=dis[j]; u=j; } } book[u]=1; //松弛判断 全局判断 for(int x=1;x<m;x++) { if(a[u][x]<M){ if(dis[x]>dis[u]+dis[u]+a[u][x]) dis[x]=dis[u]+a[u][x]; //由u作为切换点 } } } // cout<<"接过"<<endl; for(int i=1;i<m;i++) cout<<dis[i]<<endl; } int main() { // int m,n,u,v,l; 错误出现在这里 int u,v,l; cin>>m>>n; memset(a,0x7f,sizeof(a)); for(int i=0;i<n;i++){ cin>>u>>v>>l; a[u-1][v-1]=l; a[i][i]=0; } dijstra(m); }
SPFA算法:可以处理负权值(必须掌握)
//SPFA算法 可以处理负权值 处理正权值比不上dijstra #include <iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define MAX 200001 #define INF 99999999 typedef struct XNode //链表做好 { int pow;//边的权值 int adjvex;//点 struct XNode *next; }Node; Node * head[MAX]; int visit[MAX],dis[MAX];//标记与距离 void add(int u,int v,int w) { Node *p; p=(Node*)malloc(sizeof(Node)); //创建新的结点 p->pow=w; //权值 p->adjvex=v;//点 p->next=head[u]; //下一个点 head[u]=p; //出发点 } void SPFA(int n) { int u,v,w; queue<int>Q;//这个算法关键使用队列来处理问题 Node *p; for(int i=1;i<=n;i++)//初始化 { visit[i]=0; //未被访问 dis[i]=INF;//距离初始最远 } Q.push(1);//头结点进队 dis[1]=0; visit[1]=1; while(!Q.empty())//直到队列为空才结束循环 { u=Q.front();//头结点 Q.pop();//进队 for(p=head[u];p!=NULL;p=p->next) { v=p->adjvex; w=p->pow; if(dis[u]+w<dis[v]) { dis[v]=dis[u]+w; if(!visit[v]) { visit[v]=1; Q.push(v);//出队 } } } } } int main() { int n,m,u,v,w; while(cin>>n>>m){ memset(head,NULL,sizeof(head));//初始化链表 for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); } SPFA(n); for(int i=2;i<=n;i++) cout<<dis[i]<<endl; } return 0; }
bell_man算法:理解就行
2.多点最短路径问题