最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12493 Accepted Submission(s): 3786
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
Sample Output
9 11解决方案:也是一道模板题,详细算法见算法汇总code:原始的dijkstra#include<iostream> #include<cstdio> #include<cstring> #define MMAX 1003 using namespace std; const int inf=1<<30; int dist[MMAX]; int Map[MMAX][MMAX]; int value[MMAX][MMAX]; int need[MMAX]; bool vis[MMAX]; int n,m; int main() { while(~scanf("%d%d",&n,&m)&&(m+n)) { int a,b,c,d; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { Map[i][j]=i==j?0:inf; value[i][j]=i==j?0:inf; } for(int i=0; i<m; i++) { scanf("%d%d%d%d",&a,&b,&c,&d); if(Map[a][b]>c) { Map[a][b]=Map[b][a]=c; value[a][b]=value[b][a]=d; } else if(Map[a][b]==c) { value[b][a]=value[a][b]=min(value[a][b],d); } } for(int i=1; i<=n; i++) { dist[i]=inf; need[i]=inf; } int s,t; memset(vis,false,sizeof(vis)); scanf("%d%d",&s,&t); dist[s]=0; need[s]=0; for(int i=1; i<=n; i++) { int Min=inf,next; for(int j=1; j<=n; j++) { if(!vis[j]&&(Min>dist[j])) { next=j; Min=dist[j]; } } if(Min==inf)break; vis[next]=true; for(int k=1; k<=n; k++) { if(!vis[k]&&(dist[k]>=dist[next]+Map[next][k])&&Map[next][k]!=inf) { if(dist[k]>dist[next]+Map[next][k]) { dist[k]=dist[next]+Map[next][k]; need[k]=need[next]+value[next][k]; } else { need[k]=min(need[k],need[next]+value[next][k]); } } } } printf("%d %d\n",dist[t],need[t]); } return 0; }
code:优先队列优化dijkstra#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define MMAX 102 #define inf 0x7fffffff using namespace std; typedef struct node { struct node *next;///指向连接该节点的边 int adj;///边的指向 int v;///边的权值 } node,*pnode; node edge[MMAX]; typedef struct heap { bool operator<(heap T)const { return T.dis<dis; }///优先队列重载'<'符号 int dis,x; } heap; priority_queue< heap > Q; bool vis[MMAX]; int d[MMAX]; int n,m; void add_edge(int a,int b,int c) { pnode p=&edge[a]; while(p->next!=NULL) p=p->next; pnode q=new node(); q->next=NULL; q->v=c; q->adj=b; p->next=q; }///邻接矩阵加上一条边 int bfs() { while(!Q.empty()) Q.pop(); heap in,Min; in.x=1,in.dis=0; d[1]=0; Q.push(in); while(!Q.empty()) { Min=Q.top(); Q.pop(); if(Min.x==n) return Min.dis; if(vis[Min.x]) continue; vis[Min.x]=true; pnode p=edge[Min.x].next; while(p!=NULL) { if(!vis[p->adj]){ in.x=p->adj; in.dis=Min.dis+p->v; if(d[in.x]>in.dis) { d[in.x]=in.dis; Q.push(in); } } p=p->next; } } } int main() { int a,b,c; while(~scanf("%d%d",&n,&m)&&(m+n)) { for(int i=1; i<=n; i++) { edge[i].next=NULL; vis[i]=false; d[i]=inf; }///初始化每个端点 for(int i=0; i<m; i++) { scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } int Min=bfs(); printf("%d\n",Min); } return 0; }