Uva 11374 最短路 好題
阿新 • • 發佈:2019-02-03
題目連結:點我
題目大意:有n個點,求從s到e的最短路,有m條無向路可以隨意走,k條無向路最多可以走一次也可以不走;
真是不知道方法死也過不去了,知道了秒過,鍛鍊思維。
程式碼很醜見諒。
思路:求s到各個點的最短路,再求e到各點的最短路,然後列舉k條路,求出最短路然後列印路徑
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #define text cout<<"text"<<endl; using namespace std; typedef long long LL; struct node{ int y,l,next; }k[20100]; int head[510]; char rode[510]; int dis1[510],vis1[510],pre1[510]; void spfa1(int l){ for(int i=0;i<=500;i++){ dis1[i]=2000000; vis1[i]=0; pre1[i]=-1; } dis1[l]=0; vis1[l]=1; queue<int>qu; qu.push(l); while(!qu.empty()){ int x=qu.front(); qu.pop(); vis1[x]=0; for(int i=head[x];i!=-1;i=k[i].next){ int y=k[i].y; if(dis1[y]>dis1[x]+k[i].l){ dis1[y]=dis1[x]+k[i].l; pre1[y]=x; if(!vis1[y]){ vis1[y]=1; qu.push(y); } } } } } int dis2[510],vis2[510],pre2[510]; void spfa2(int l){ for(int i=0;i<=500;i++){ dis2[i]=2000000; vis2[i]=0; pre2[i]=-1; } dis2[l]=0; vis2[l]=1; queue<int>qu; qu.push(l); while(!qu.empty()){ int x=qu.front(); qu.pop(); vis2[x]=0; for(int i=head[x];i!=-1;i=k[i].next){ int y=k[i].y; if(dis2[y]>dis2[x]+k[i].l){ dis2[y]=dis2[x]+k[i].l; pre2[y]=x; if(!vis2[y]){ vis2[y]=1; qu.push(y); } } } } } int main(){ int S,E,N,M,K,flog=0; while(cin>>N>>S>>E){ if(flog)printf("\n"); else flog=1; int x,y,z,h=0; memset(head,-1,sizeof(head)); scanf("%d",&M); while(M--){ scanf("%d%d%d",&x,&y,&z); k[h].y=y; k[h].l=z; k[h].next=head[x]; head[x]=h++; k[h].y=x; k[h].l=z; k[h].next=head[y]; head[y]=h++; } spfa1(S); spfa2(E); int time=dis1[E]; int change1=-1,change2=-1; scanf("%d",&K); for(int i=0;i<K;i++){ scanf("%d%d%d",&x,&y,&z); int t1=dis1[x]+dis2[y]+z; if(t1<time){ time=t1; change1=x; change2=y; } int t2=dis1[y]+dis2[x]+z; if(t2<time){ time=t2; change1=y; change2=x; } } if(change1==-1){ int ch[1100]; int i=E,len=0; memset(ch,0,sizeof(ch)); while(1){ ch[len++]=i; i=pre1[i]; if(i==-1)break; } for(int i=len-1;i>=0;i--){ printf("%d",ch[i]); if(i)printf(" "); } printf("\nTicket Not Used\n"); } else { int ch[1100]; int i=change1,len=0; memset(ch,0,sizeof(ch)); while(1){ ch[len++]=i; i=pre1[i]; if(i==-1)break; } for(int i=len-1;i>=0;i--){ printf("%d",ch[i]); if(i)printf(" "); } memset(ch,0,sizeof(ch)); i=change2; while(1){ printf(" %d",i); i=pre2[i]; if(i==-1)break; } printf("\n%d\n",change1); } cout<<time<<endl; } return 0; }