必须二刷不废话
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> mindis,mint;
int sr,fin,dispre[509],tpre[509];
int n,m,a[509][509],t[509][509],_1,_2,_3,_4,_5,visit[509]={0},dist1,t1,u,distsr[509],pred=-1,tsr[509],num[509]={1} ;
const int inf=999999999;
void disdfs(int end)
{mindis.push_back(end);
if(end==sr)//向前找倒序
return;
disdfs(dispre[end]);
}
void tdfs(int end1)
{mint.push_back(end1);
if(end1==sr) return;
tdfs(tpre[end1]);
}
int main()
{ //当变量特别大时不能放到main函数里会溢出,变成全局变量放在main外 dijkstra问题都放在main外(注意)
//int n,m,a[509][509],t[509][509],_1,_2,_3,_4,_5,visit[509]={0},dist1,t1,u,distsr[509],pred=-1,tsr[509],num[509]={1} ;
fill(a[0],a[0]+509*509,inf);
fill(t[0],t[0]+509*509,inf);
fill(distsr,distsr+509,inf);
fill(tsr,tsr+509,inf);
cin>>n>>m;
for(int i=0;i<m;i++)
{cin>>_1>>_2>>_3>>_4>>_5;
a[_1][_2]=_4;
if(_3==0) a[_2][_1]=_4;
t[_1][_2]=_5;
if(_3==0)t[_2][_1]=_5;
}
cin>>sr>>fin;
//init
distsr[sr]=0;//必要相当于钥匙
for(int i=0;i<n;i++)
dispre[i]=i;
for(int j=0;j<n;j++){
u=-1,dist1=inf;//-1来判断连不连通
for(int i=0;i<n;i++){
if(visit[i]==0&&distsr[i]<dist1)
{dist1=distsr[i];
u=i;
}
}
if(u==-1) break;
visit[u]=1;//visit[sr]=1;他会自动将sr弄成1
for(int v=0;v<n;v++)
{//在v-s集合中访问其他元素
if(visit[v]==0&&distsr[u]+a[u][v]<distsr[v]&&a[u][v]!=inf)
{
distsr[v]=distsr[u]+a[u][v];
dispre[v]=u;
tsr[v]=tsr[u]+t[u][v];
}
else if(visit[v]==0&&distsr[u]+a[u][v]==distsr[v]&&a[u][v]!=inf&&tsr[u]+t[u][v]<tsr[v])
{
dispre[v]=u;
tsr[v]=tsr[u]+t[u][v];
}
}
}
disdfs(fin);
tsr[sr]=0;
//for(int i=0;i<n;i++)
//tpre[i]=i;
fill(visit,visit+509,0);
//这样没用不会改变,只有在局部变量初始化或全局变量声明时才有用 (注意)
//visit[509]={0};
for(int i=0;i<n;i++)
{ u=-1,t1=inf;
for(int j=0;j<n;j++)
{
if(visit[j]==0&&tsr[j]<t1)
{
t1=tsr[j];
u=j;
}
}
if(u==-1) break;
visit[u]=1;
for(int v=0;v<n;v++)
{
if(visit[v]==0&&t[u][v]!=inf)
{
if(tsr[u]+t[u][v]<tsr[v])
{
tsr[v]=tsr[u]+t[u][v];
tpre[v]=(u) ;
num[v]=num[u]+1;}
else if(tsr[u]+t[u][v]==tsr[v]&&num[v]>num[u]+1)
{ num[v]=num[u]+1;
tpre[v]=(u) ;
}
}
}
}
tdfs(fin);
if(mindis==mint)
{ printf("Distance = %d;",distsr[fin]);
printf(" Time = %d: ",tsr[fin]);
for(int i=mindis.size()-1;i>=0;i--)
{ if(i!=mindis.size()-1) printf(" -> ");
printf("%d",mindis[i]);
}
}
else{
printf("Distance = %d: ",distsr[fin]);
for(int i=mindis.size()-1;i>=0;i--)
{ if(i!=mindis.size()-1) printf(" -> ");
printf("%d",mindis[i]);}
printf("\n");
printf("Time = %d: ",tsr[fin]);
for(int i=mint.size()-1;i>=0;i--)
{if(i!=mint.size()-1) printf(" -> ");
printf("%d",mint[i]);
}
}
return 0;
}
总结
1、没输在逻辑上,输在对编译器的了解上
有非常大的数据时声明要声明为全局变量,main函数以外,否则会被毙掉 以后dijkstra全部声明在外面!!!
2. visit[509]={0}; 是没有用的!!!坑死我了
局部 int visit[509]={0} 可以
全局直接声明 int visit[509]可以
fill(visit,visit+509,0)可以 要加上头文件 algorithm
英语:
问题
dijkstra 3个准备 3个for一个套2个 再多写写