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