最短路径 | 1087 三重标尺+记录最短路径条数
这题可谓最短路的集大成。map或字符串hash的输入处理、多重标尺、最短路径条数。
但是这都是纸老虎,搞清楚逻辑和概念,所有问题迎刃而解。
代码是在宿舍写的。因为声音比较嘈杂,导致写了个很傻比的bug,调了很久。
#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[LEN][LEN]; int vis[LEN]; int dist[LEN]; int pre[LEN]; int hap_s[LEN]; int hap[LEN]; int way_cnt[LEN]; int v_cnt[LEN]; map<string,int> name2id; string id2name[LEN] ; int nID=1; int e; int getID(string s){ int i=name2id[s]; if(i){ return i; }else{ if(s=="ROM") e=nID; name2id[s]=nID; id2name[nID]=s; return nID++; } } int main(){ // freopen("I:\\pat\\最短路径\\1087.txt","r",stdin); int n,m,s,i,j,a,b,c; char buf[100]; char str1[100]; char str2[100]; I("%d%d%s",&n,&m,buf); s=getID(buf); FF(i,n-1){ I("%s%d",buf,&a); hap_s[getID(buf)]=a; } fill(g[0],g[0]+LEN*LEN,MAX); fill(dist,dist+LEN,MAX) ; FF(i,m){ I("%s%s%d",str1,str2,&c); a=getID(str1); b=getID(str2); g[b][a]=g[a][b]=c; } dist[s]=0; hap[s]=hap_s[s]; way_cnt[s]=1; pre[s]=-1; v_cnt[s]=0; while(1){ int u=-1,d=MAX; F(i,1,nID) if(!vis[i] && dist[i]<d){ d=dist[i]; u=i; } if(u<0) break; vis[u]=1; F(i,1,nID) if(!vis[i]){ if(dist[u]+g[u][i]<dist[i]){ dist[i]=dist[u]+g[u][i]; way_cnt[i]=way_cnt[u]; // hap[i]=hap[u]+hap_s[i]; pre[i]=u; v_cnt[i]=v_cnt[u]+1; }else if(dist[u]+g[u][i]==dist[i]){ way_cnt[i]+=way_cnt[u]; if(hap[u]+hap_s[i]>hap[i] || (hap[u]+hap_s[i]==hap[i] && v_cnt[u]+1<v_cnt[i])){ hap[i]=hap[u]+hap_s[i]; pre[i]=u; v_cnt[i]=v_cnt[u]+1; } } } } vector<string> path; i=e; while(i>=0){ path.insert(path.begin(),id2name[i]); i=pre[i]; } printf("%d %d %d %d\n",way_cnt[e],dist[e],hap[e],hap[e]/v_cnt[e]); FF(i,path.size()){ O("%s",path[i].c_str()); if(i!=path.size()-1) O("->"); } return 0; }