編號爲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);
}