编号为1到N的N个城市间有M条铁路,通过每条铁路花费时间T_i,为了减少从城市1到N的时间,现在决定将其中一条铁路改建成高铁,改建后通过该条铁路的时间将减半(向下取整数),求改建哪条铁路可以使得改建后从城市1到城市N的时间最短
输入:第一行N和M
接下来M行,每行A_i, B_i, T_i分别是第i条铁路的起点和终点,以及时间
输出:改建的铁路编号以及改建后从1到N的时间
注意:铁路是双向的,保证解唯一
80%数据N,M<5000,100%数据N,M<1000000;
dij算法的深刻理解
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1000010;
struct edge
{
int end;
int time;
edge(int e,int t)
{
end=e;
time=t;
}
bool operator <(const edge& a)const
{
return time>a.time;
}
};
struct bridge{
int u,v,t;
} bridges[maxn];
const int inf=0x3f3f3f3f;
int n,m;
int to1[maxn],ton[maxn];
vector<edge> edges[maxn];
priority_queue<edge> p;
void dij(int s,int * tem)
{
for(int i=1;i<=n;i++)
{
tem[i]=inf;
}
tem[s]=0;
p.push(edge(s,0));
while(!p.empty())
{
int temend=p.top().end;
int temtime=p.top().time;
p.pop();//fotget first time!!!!!!!!!!
if(temtime!=tem[temend])
{
continue;
}
for(int i=0;i<edges[temend].size();i++)
{
int f=edges[temend][i].end;
int d=edges[temend][i].time;
if(tem[temend]+d<tem[f])
{
tem[f]=tem[temend]+d;
p.push(edge(f,tem[temend]+d));
}
}
}
for(int i=1;i<=n;i++)
{
cout<<tem[i]<<" ";
}
cout<<endl;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
bridges[i].u=u;
bridges[i].v=v;
bridges[i].t=t;
edges[u].push_back(edge(v,t));
edges[v].push_back(edge(u,t));
}
dij(1,to1);
dij(n,ton);
int res=inf,idx;
for(int i=1;i<=m;++i){
int u=bridges[i].u,v=bridges[i].v;
int tmp=to1[u]+ton[v]+bridges[i].t/2;
if(tmp<res){
res=tmp;
idx=i;
}
}
printf("%d %d\n",idx,res);
}