题目描述
有一个邮递员要送东西,邮局在节点 1。他总共要送 n-1样东西,其目的地分别是节点 2到节点 n。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有 m条道路。这个邮递员每次只能带一样东西,并且运送每件物品过后必须返回邮局。求送完这 n-1 样东西并且最终回到邮局最少需要的时间。
输入格式
输出格式
输出仅一行,包含一个整数,为最少需要的时间。
输入输出样例
输入 :
5 10
2 3 5
1 5 5
3 5 6
1 2 8
1 3 8
5 3 4
4 1 8
4 5 3
3 5 6
5 4 2
输出:
83
题目分析:
1.单源最短路径题目,推荐用Dijkstra算法。
2.注意是来回两个方向,所以需要反向建图。 (邻接表/邻接矩阵都行)
3.注意翻转数组,反向建图。
4.以及邻接矩阵的初始化(自己本身的点仍为0,其余点均设为无穷大),初始赋值(从1点到各个结点的时间)。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int mp[1010][1010],dis[1010];
const int INF=1e9;
int i,j;
void init(int n);//初始化邻接矩阵
void dijkstra(int n);
void over(int n);//翻转邻接矩阵,即反向建立邻接矩阵
void lujing(int n);//将1到各个点初始赋值
int main()
{
int n,m,x,y,w;
int sum;
cin>>n>>m;
init(n);
for(i=1;i<=m;i++)
{
cin>>x>>y>>w;
mp[x][y]=min(mp[x][y],w);//建图,防止重复边
}
lujing(n);
dijkstra(n);
for(i=1;i<=n;i++)
{
sum+=dis[i];
}
over(n);//翻转邻接矩阵
lujing(n);
dijkstra(n);
for(i=1;i<=n;i++)
{
sum+=dis[i];
}
cout<<sum<<endl;
}
void init(int n)//邻接矩阵初始化
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i!=j)
mp[i][j]=INF;
}
}
}
void dijkstra(int n)//单源最短路径
{
bool vis[1010]={0};
vis[1]=1;
for(i=1;i<n;i++)
{
int min=INF;int index;
for(j=1;j<=n;j++)
{
if(!vis[j]&&min>dis[j])
{
min=dis[j];
index=j;
}
}
vis[index]=1;
for(j=1;j<=n;j++)
{
if(!vis[j]&&mp[index][j]+dis[index]<dis[j])//更新
{
dis[j]=mp[index][j]+dis[index];
}
}
}
}
void over(int n)
{
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
int temp=0;
temp=mp[i][j];
mp[i][j]=mp[j][i];
mp[j][i]=temp;
}
}
}
void lujing(int n){
for(i=1;i<=n;i++){
dis[i]=mp[1][i];
}
}
第一次写题目写了近100行代码,好累啊,想了一晚上,加上查资料啥的,永远秉承费费的教导,不懂得题不睡也要肝,生死看淡,不服就干,最短路问题持续更新...