最短路径已经考腻了,已经在往模拟的趋势上发展。今天顺便还练习了一下前向星,感觉很好用,以后都用前向星了。
#include <stdio.h> #include <memory.h> #include <math.h> #include <string> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 1010 #define MAX (1<<30)-1 #define V vector<int> using namespace std; int head[LEN]; int vis[LEN]; struct edge{ int to,next,dist,Time; }mp[LEN*LEN]; int eID=0; void add(int u,int v,int dist,int Time){ mp[eID].to=v; mp[eID].dist=dist; mp[eID].Time=Time; mp[eID].next=head[u]; head[u]=eID++; } int N,M,s,e; int dist[LEN]; int Time[LEN]; int pre[LEN]; int cnt[LEN]; vector<int> path1; vector<int> path2; int minDist; int minTime; void printPath(vector<int>& p){ int sz=p.size(); int i; FF(i,sz){ O("%d",p[i]); if(i!=sz-1) O(" -> "); } puts(""); } bool pathEqual(){ if(path1.size()!=path2.size()) return false; int i; FF(i,path1.size()){ if(path1[i]!=path2[i]) return false; } return true; } void dij_1(){//获得最短路径。如果最短路径不唯一,输出最快路径 fill(dist,dist+LEN,MAX); fill(Time,Time+LEN,MAX); fill(vis,vis+LEN,0); fill(pre,pre+LEN,-1); dist[s]=0; Time[s]=0; int i; while(1){ int u=-1,min_d=MAX; FF(i,N) if(!vis[i] && dist[i]<min_d){ min_d=dist[i]; u=i; } if(u<0) break; vis[u]=1; for(i=head[u];~i;i=mp[i].next){ int to=mp[i].to; if(!vis[to]){//s->u + u->to if(dist[u]+mp[i].dist<dist[to] || (dist[u]+mp[i].dist==dist[to] && Time[u]+mp[i].Time<Time[to])){ dist[to]=dist[u]+mp[i].dist; Time[to]=Time[u]+mp[i].Time; pre[to]=u; } } } } i=e; while(i>=0){ path1.insert(path1.begin(),i); i=pre[i]; } minDist=dist[e]; } void dij_2(){//获得最快路径。如果路径不唯一,输出经过点最少的路径 fill(Time,Time+LEN,MAX); fill(vis,vis+LEN,0); fill(pre,pre+LEN,-1); Time[s]=0; int i; while(1){ int u=-1,min_d=MAX; FF(i,N) if(!vis[i] && Time[i]<min_d){ min_d=Time[i]; u=i; } if(u<0) break; vis[u]=1; for(i=head[u];~i;i=mp[i].next){ int to=mp[i].to; if(!vis[to]){//s->u + u->to if(Time[u]+mp[i].Time<Time[to] || (Time[u]+mp[i].Time==Time[to] && cnt[u]+1<cnt[to])){ Time[to]=Time[u]+mp[i].Time; cnt[to]=cnt[u]+1; pre[to]=u; } } } } i=e; while(i>=0){ path2.insert(path2.begin(),i); i=pre[i]; } minTime=Time[e]; } int main(){ // freopen("I:\pat\最短路径\1111_2.txt","r",stdin); memset(head,-1,sizeof(head)); I("%d%d",&N,&M); int i,j,u,v,o,d,t; FF(i,M){ I("%d%d%d%d%d",&u,&v,&o,&d,&t); add(u,v,d,t); if(o==0) //不是单程路 add(v,u,d,t); } I("%d%d",&s,&e); dij_1(); dij_2(); if(pathEqual()){ O("Distance = %d; Time = %d: ",minDist,minTime); printPath(path1); }else{ O("Distance = %d: ",minDist); printPath(path1); O("Time = %d: ",minTime); printPath(path2); } return 0; }