旅游规划这个题,其实用floyd也可以做,而且代码看起来更舒服,先给一个floyd的代码(非全原创,侵删),但要注意,由于floyd确实多算了很多无用的数据,如果卡你时间,floyd是过不了的。
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int node [505][505];
int dis[505][505];
int main()
{
int n,m,s,d,i,j,k,x,y,q,w;
cin>>n>>m>>s>>d;
memset(dis,INF,sizeof(dis));
memset(node,INF,sizeof(node));
for(int i=0;i<n;i++)
{
dis[i][i]=0;
node[i][i]=0;
}
for(i=0; i<m; i++)
{
scanf("%d %d %d %d",&x,&y,&q,&w);
node[x][y] = node[y][x] = q;
dis[x][y] = dis[y][x] = w;
}
for(k=0; k<n; k++)
{
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(node[i][j]>node[i][k]+node[k][j]||(node[i][j]==node[i][k]+node[k][j]&&dis[i][j]>dis[i][k]+dis[k][j]))
{
node[i][j] = node[i][k]+node[k][j];
dis[i][j] = dis[i][k]+dis[k][j];
}
}
}
}
printf("%d %d\n",node[s][d],dis[s][d]);
return 0;
}
dijkstra算法(非全原创,侵删)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f;
using namespace std;
int n,m,s,d;
int G[505][505];
int a[505][505];
int lowcost[505];
int fee[505];
int vis[505];
void dij()
{
for(int i=0;i<n;i++)
{
lowcost[i]=INF;
}
lowcost[s]=0;
for(int mm=0;mm<n;mm++)
{
int minn=INF;
int k=-1;
for(int i=0;i<n;i++)
{
if(lowcost[i]<=minn && vis[i]==0)
{
minn=lowcost[i];
k=i;
}
}
vis[k]=1;
for(int i=0;i<n;i++)
{
if(vis[i]==0&&lowcost[i]==lowcost[k]+G[k][i]) //不写vis[i]==0也对,但是会浪费时间
{
if(fee[i]>fee[k]+a[k][i])
{
fee[i]=fee[k]+a[k][i];
}
}
else if(vis[i]==0&&lowcost[i]>lowcost[k]+G[k][i])
{
lowcost[i]=lowcost[k]+G[k][i];
fee[i]=fee[k]+a[k][i];
}
}
}
}
int main()
{
scanf("%d %d %d %d",&n,&m,&s,&d);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i!=j)
G[i][j]=G[j][i]=INF;
}
}
while(m--)
{
int x,y,l,f;
scanf("%d %d %d %d",&x,&y,&l,&f);
G[x][y]=G[y][x]=l;
a[x][y]=a[y][x]=f;
}
dij();
printf("%d %d\n",lowcost[d],fee[d]);
return 0;
}
城市间紧急救援这个题我认为比上面那个考的更加全面和具体,比如他要求输出路径,要求输出最短路径条数,比起上个题,此题更有挑战性,做出来收获更大。
代码是我在网上找的,因为很好,比我自己的好太多,所以我只改了一个变量名,侵删。
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int a[1001][1001];
int cnt[1001],vis[1001]= {0},cf[1001],ccf[1001],pre[1001];
//最短路径条数,各城市是否经过,各城市的救援队数量,到达该城市时所召集的所有救援队数量,到达该城市前经过的城市编号
int n,m,s,d;
int Dijkstra()
{
cnt[s]=1;//开始时路径条数为1
vis[s]=1;//当前在出发城市
for(int i=0; i<n; i++)
{
int min=inf,f=-1;
for(int j=0; j<n; j++)
{
if(vis[j]==0&&a[s][j]<min) //寻找下一个距离最短的城市
{
min=a[s][j];
f=j;//做好下一城市编号的标记
}
}
if(f==-1)break;//与其他未经过的城市不连通,退出循环
else vis[f]=1;//到达下一城市
for(int j=0; j<n; j++)
{
if(vis[j]==0&&a[s][j]>a[s][f]+a[f][j]) //到达某一城市的最短路径
{
a[s][j]=a[s][f]+a[f][j];//最短路径更新
pre[j]=f;//记录上一个城市编号
cnt[j]=cnt[f];//拷贝到达上一个城市时的最短路径条数
ccf[j]=ccf[f]+cf[j];//到达某城市召集的全部救援队数量
}
else if(vis[j]==0&&a[s][j]==a[s][f]+a[f][j]) //发现其他的最短路径
{
cnt[j]=cnt[j]+cnt[f];//更新到达当前城市时的最短路径条数
if(ccf[j]<ccf[f]+cf[j]) //最多救援队数量更新
{
pre[j]=f;//记录所经过的上一个城市编号
ccf[j]=ccf[f]+cf[j];//更新救援队总数
}
}
}
}
}
int main()
{
cin>>n>>m>>s>>d;
for(int i=0; i<n; i++)
{
cin>>cf[i];
ccf[i]=cf[i];
cnt[i]=1;
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(i!=j)a[i][j]=a[j][i]=inf;//初始化(双向图)
}
}
for(int i=0; i<m; i++)
{
int q,w,e;
cin>>q>>w>>e;
a[q][w]=a[w][q]=e;
}
Dijkstra();
cout<<cnt[d]<<" "<<ccf[d]+cf[s]<<endl;//注意ccf[d]要与cf[s]相加
int road[1001];
int x=0,t=d;
while(pre[t]!=0) //所经历的城市的从后往前的顺序
{
road[x++]=pre[t];
t=pre[t];
}
cout<<s;//出发地
for(int i=x-1; i>=0; i--)
cout<<" "<<road[i];
cout<<" "<<d;//目的地
}