题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4179
思路:不知道怎么回事,wa了n多次,然后不知道怎么回事就过了==,还是简单的说一下思路吧:一次以起点为源点跑一遍spfa,然后以终点为起点跑一次spfa,这样我们就可以枚举difficult为maxdist的边了,设该边的端点为x,y,于是有ans=min(ans,dist1[x]+Get_Dist(x,y)+dist2[y])。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 #include<cmath> 8 using namespace std; 9 typedef pair<int,double>Pair; 10 #define MAXN 44444 11 #define inf 1e16 12 double dist1[MAXN],dist2[MAXN]; 13 bool mark[MAXN]; 14 struct Edge{ 15 int v; 16 double w; 17 Edge(){} 18 Edge(int _v,double _w){ 19 v=_v,w=_w; 20 } 21 }; 22 vector<Edge>map1[MAXN],map2[MAXN]; 23 vector<int>vet; 24 struct Point{ 25 int x,y,z; 26 }point[MAXN]; 27 28 struct Node{ 29 int vs,vt; 30 }node[MAXN]; 31 int n,m,st,ed,maxdist; 32 33 double Get_Dist(int vs,int vt){ 34 double xx=1.0*(point[vs].x-point[vt].x)*(point[vs].x-point[vt].x); 35 double yy=1.0*(point[vs].y-point[vt].y)*(point[vs].y-point[vt].y); 36 double zz=1.0*(point[vs].z-point[vt].z)*(point[vs].z-point[vt].z); 37 return sqrt(xx+yy+zz); 38 } 39 40 int Get(int vs,int vt){ 41 if(point[vs].z<point[vt].z){ 42 double xx=1.0*(point[vs].x-point[vt].x)*(point[vs].x-point[vt].x); 43 double yy=1.0*(point[vs].y-point[vt].y)*(point[vs].y-point[vt].y); 44 double dd=sqrt(xx+yy); 45 return (int)(100*(point[vt].z-point[vs].z)/dd); 46 } 47 return 0; 48 } 49 50 void SPFA(int st,vector<Edge>map[],double dist[]) 51 { 52 memset(mark,false,(n+2)*sizeof(mark[0])); 53 for(int i=1;i<=n;i++)dist[i]=inf; 54 dist[st]=0;mark[st]=true; 55 queue<int>Q; 56 Q.push(st); 57 while(!Q.empty()){ 58 int u=Q.front(); 59 Q.pop(); 60 mark[u]=false; 61 for(int i=0;i<map[u].size();i++){ 62 int v=map[u][i].v; 63 double w=map[u][i].w; 64 if(dist[u]+w<dist[v]){ 65 dist[v]=dist[u]+w; 66 if(!mark[v]){ mark[v]=true;Q.push(v); } 67 } 68 } 69 } 70 } 71 72 73 int main() 74 { 75 // freopen("1.txt","r",stdin); 76 while(scanf("%d%d",&n,&m),(n+m)){ 77 for(int i=1;i<=n;i++){ map1[i].clear();map2[i].clear();}; 78 vet.clear(); 79 for(int i=1;i<=n;i++){ 80 scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].z); 81 } 82 for(int i=1;i<=m;i++){ 83 scanf("%d%d",&node[i].vs,&node[i].vt); 84 } 85 scanf("%d%d%d",&st,&ed,&maxdist); 86 for(int i=1;i<=m;i++){ 87 double dd=Get_Dist(node[i].vs,node[i].vt); 88 int d1=Get(node[i].vs,node[i].vt); 89 int d2=Get(node[i].vt,node[i].vs); 90 if(d1<=maxdist){ 91 map1[node[i].vs].push_back(Edge(node[i].vt,dd)); 92 map2[node[i].vt].push_back(Edge(node[i].vs,dd)); 93 } 94 if(d2<=maxdist){ 95 map1[node[i].vt].push_back(Edge(node[i].vs,dd)); 96 map2[node[i].vs].push_back(Edge(node[i].vt,dd)); 97 } 98 if(d1==maxdist){ 99 vet.push_back(node[i].vs); 100 vet.push_back(node[i].vt); 101 } 102 if(d2==maxdist){ 103 vet.push_back(node[i].vt); 104 vet.push_back(node[i].vs); 105 } 106 } 107 SPFA(st,map1,dist1); 108 SPFA(ed,map2,dist2); 109 double ans=inf; 110 for(int i=0;i<vet.size();i+=2){ 111 int x=vet[i],y=vet[i+1]; 112 double dd=dist1[x]+Get_Dist(x,y)+dist2[y]; 113 if(dd<ans)ans=dd; 114 } 115 if(ans<inf){ 116 printf("%.1lf\n",ans); 117 }else 118 puts("None"); 119 } 120 return 0; 121 }