9.9-铁路修建-双dij

编号为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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章