既然题目写了Dijkstra,那我就用Dijkstra算法去做咯。
是什么:找到两点之间的第一最短和第二无重复路径最短距离
为什么:寻求最短路
怎么样:用Dijstra找到第一条最短路,把第一条最短路的路径和反向的路径都标记上。再用dijstra找第二条无标记路径的最短路。
可是就是不知道为什么WA了 T_T
以下是没有过的代码(样例过了,自己拼凑的例子也没错虽然不多= =)
update:(思考了一 下,这个思路是错的。后面给出反例)
#include<ostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
struct edge{
int s,e,w,next,used,fa;
edge(int a=0,int b=0,int c=0){
s=a;e=b;w=c;
used=0;
fa=-1;
}
};
int start[110],mark[110],d[110];
edge data[30000];
int n,m;
int dijkstra(){
d[0]=0;
int lar,bian,ok=1;
memset(&lar,0x3f,sizeof(lar)); //捉急的赋值。。。
while(ok){
ok=0;
for(int x=start[1];x!=-1;x=data[x].next){
if((lar>data[x].w)&&(data[x].used==0)){
lar=data[x].w;
bian=x;
++ok;
d[data[x].e]=data[x].w;
}
}
if(ok==0) return d[n];
data[bian].used=1;
if((bian-1>0)&&((data[bian].e==data[bian-1].s))&&(data[bian].s==data[bian-1].e))
data[bian-1].used=1;
if((data[bian].s==data[bian+1].e)&&(data[bian].e==data[bian+1].s))
data[bian+1].used=1;
if(n==1){
d[data[bian].e]=data[bian].w;
return d[n];
}
for(int y=start[data[bian].e];y!=-1;y=data[y].next){
if(d[data[y].e]>data[y].w+data[bian].w){
d[data[y].e]=data[y].w+data[bian].w;
data[y].fa=bian;
data[y].used=1;
if((y-1>0)&&(data[y].e==data[y-1].s)&&(data[y].s==data[y-1].e)) data[y-1].used=1;
if((data[y].s==data[y+1].e)&&(data[y].e==data[y+1].s)) data[y+1].used=1;
}
}
}
return d[n];
}
int main(){
while(scanf("%d",&n)&&n){
scanf("%d",&m);
memset(start,-1,sizeof(start));
int k=0;
memset(d,0x3f,sizeof(d));
for(int i=0;i<m;++i){
int ts,te,tw;
scanf("%d%d%d",&ts,&te,&tw);
edge tmp(ts,te,tw);
edge tmp1(te,ts,tw);
data[k]=tmp;
data[k].next=start[ts];
start[ts]=k;
++k;
data[k]=tmp1;
data[k].next=start[te];
start[te]=k;
++k;
}
int ans=dijkstra();
memset(d,0x3f,sizeof(d));
int tmp=dijkstra();
int ttmp;
memset(&ttmp,0x3f,sizeof(int));
if(tmp==ttmp) printf("Back to jail\n");
else printf("%d\n",ans+tmp);
}
return 0;
}
以下是反例
图中是有两条路的,而当第一条最短路一旦选择了中间那条连接2 ,3的路径,那答案就是“Back to jail”了,所以思路(看到题目写Dijkstra就用Dijkstra的“可爱”想法)是错的。
(持续update中...)