最短路径 | 1030 两重标尺下的最短路径
只要心里有斯杰斯特拉,多少重标尺都是浮云。
可以看到,进行多重标尺判断的时候,可以用
if(dist[u]+g_dist[u][i]<dist[i] || (dist[u]+g_dist[u][i]==dist[i] && cost[u]+g_cost[u][i]<cost[i])){
这样的骚代码来进行二重标尺的判断。但是如果要记录最短路径条数或者其他骚操作,就不能这么简洁了。
完整代码:
#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 g_dist[LEN][LEN]; int g_cost[LEN][LEN]; int vis[LEN]; int dist[LEN]; int cost[LEN]; int pre[LEN]; int main(){ // freopen("1030.txt","r",stdin); int n,m,s,e,i,j,a,b,c,d,t; I("%d%d%d%d",&n,&m,&s,&e); fill(g_dist[0],g_dist[0]+LEN*LEN,MAX); FF(i,m){ I("%d%d%d%d",&a,&b,&c,&d); g_dist[a][b]=c; g_dist[b][a]=c; g_cost[a][b]=d; g_cost[b][a]=d; } fill(dist,dist+LEN,MAX); fill(cost,cost+LEN,MAX); dist[s]=0; cost[s]=0; pre[s]=-1; while(1){ int u=-1,d=MAX; FF(i,n) if(!vis[i] && dist[i]<d){ u=i; d=dist[i]; } if(u<0) break; vis[u]=1; FF(i,n) if(!vis[i]){ if(dist[u]+g_dist[u][i]<dist[i] || (dist[u]+g_dist[u][i]==dist[i] && cost[u]+g_cost[u][i]<cost[i])){ dist[i]=dist[u]+g_dist[u][i]; cost[i]=cost[u]+g_cost[u][i]; pre[i]=u; } } } vector<int> path; i=e; while(i!=-1){ path.insert(path.begin(),i); i=pre[i]; } FF(i,path.size()) O("%d ",path[i]); printf("%d %d\n",dist[e],cost[e]) ; return 0; }