想找一道Dijkstra’s algorithm算法的题,由于leetcode上面没有相关的标签,搜索也不好搜,就找了sicily上面的一道题。许久没做sicily上的题,两个平台确实有所差异(leetcode不是纯黑盒测试,会提示哪组样例没过),确实还真有点不习惯,一些常见的坑全被我跳进去了,交了20次左右,time limited和wrong answer好久,最后才找到了两处小错误。
原题链接:http://soj.sysu.edu.cn/1031
思路:本题基本上就是裸的Dijkstra’s algorithm,算法原理这里不赘述。卡题的原因总结如下:(1)time limited是因为c--
这一句放在了while循环的最后面,导致在某个样例continue之后c一直没有做c--
,所以变成死循环。由于在找错的过程中刚开始以为是算法的逻辑错误导致某组样例出现了死循环,所以一开始一直搞错了方向(2)wrong answer是因为cout<<"-1"<<endl
这一句,没加双引号,汗,一开始排错的方向也一直是算法某些特殊样例没过。(3)其实本题还有一些情况需要考虑。比如图可能不连通;比如,最后可能问的是a到a的距离;再比如,可能问的是a到z的距离,而z在前面没出现过。这里就不一一而足了。
代码如下:
//C-- can't put at the last of while because of so many "continue" and "break"
//the output -1 and 0 must be outputted as "-1" and "0"
#include <iostream>
#include <string>
using namespace std;
int main(){
int C;
cin>>C;
while(C>0){
//C-- can't put at the last of while because of so many "continue" and "break"
C--;
//v[201] stores the places
string v[201];
//distance[201][201] stores the distance between the places
int distance[201][201];
//nplace means the nums of places
int nplace=0;
//res1,res2 represents the places which the program want to know the shortest distance between them
string res1,res2;
int res_x=0,res_y=0;
//initializate
for(int i=0;i<201;i++){
v[i]="";
for(int j=0;j<201;j++)
if(i==j)
distance[i][j]=0;
else
distance[i][j]=300000;
}
int len;
int N;
cin>>N;
//store the places and distance between them, the string places are changed to int.
while(N--){
string a,b;
cin>>a>>b>>len;
int xi,yi;
//flag1 and flag2 are flags to judge whether the place has appeared before
bool flag1=false,flag2=false;
for(int i=1;i<=nplace;i++){
if(v[i]==a){
xi=i;
flag1=true;
}
if(v[i]==b){
yi=i;
flag2=true;
}
}
if(!flag1){
nplace++;
xi=nplace;
v[nplace]=a;
}
if(!flag2){
if(a!=b){
nplace++;
v[nplace]=b;
}
yi=nplace;
}
distance[xi][yi]=len;
distance[yi][xi]=len;
}
cin>>res1>>res2;
//find the index of res1 and res2 in v[201],if can't find it,res_x=0,res_y=0
for(int i=1;i<=nplace;i++){
if(v[i]==res1)
res_x=i;
if(v[i]==res2)
res_y=i;
}
//the same place
if(res1==res2){
cout<<"0"<<endl;
continue;
}
//if the place res1 or res2 havn't appeared before, one of res_x,res_y must be 0
if((res_x==0)||(res_y==0))
{
cout<<"-1"<<endl;
continue;
}
//Dijkstra's algorithm
bool visited[201];
int pre;
int res_x_to_others[201];
bool fg=false;
for(int i=1;i<201;i++){
res_x_to_others[i]=300000;
visited[i]=false;
}
visited[res_x]=true;
pre=res_x;
res_x_to_others[res_x]=0;
for(int i=1;i<=nplace;i++){
int min=300000;
//find the place which has the shortest distance
for(int j=1;j<=nplace;j++){
if((!visited[j])&&(res_x_to_others[j]<min)){
min=res_x_to_others[j];
pre=j;
}
}
//pre means the last place visit
visited[pre]=true;
//find out res2,cout the result
if(pre==res_y){
cout<<res_x_to_others[pre]<<endl;
fg=true;
break;
}
//update the distance
for(int j=1;j<=nplace;j++){
if((!visited[j])&&(res_x_to_others[pre]+distance[pre][j]<res_x_to_others[j])){
res_x_to_others[j]=res_x_to_others[pre]+distance[pre][j];
}
}
}
//can't find res2 means res1 can't connect to res2
if(!fg)
cout<<"-1"<<endl;
}
return 0;
}
代码确实写得比较挫,也谈不上什么OO原则,一开始纯粹就是想过题,习惯也不好。后面加了很多注释以便理解。之后应该还会对这个算法进行总结和整理。