您的位置:首页 > 其它

Uva 11374 最短路 好题

2016-07-12 12:33 295 查看
题目链接:点我

题目大意:有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: