CSP 交通規劃

 
問題描述
  G國國王來中國參觀後,被中國的高速鐵路深深的震撼,決定爲本身的國家也建設一個高速鐵路系統。
  建設高速鐵路投入很是大,爲了節約建設成本,G國國王決定不新建鐵路,而是將已有的鐵路改形成高速鐵路。如今,請你爲G國國王提供一個方案,將現有的一部分鐵路改形成高速鐵路,使得任何兩個城市間均可以經過高速鐵路到達,並且從全部城市乘坐高速鐵路到首都的最短路程和原來同樣長。請你告訴G國國王在這些條件下最少要改造多長的鐵路。
輸入格式
  輸入的第一行包含兩個整數 nm,分別表示G國城市的數量和城市間鐵路的數量。全部的城市由1到 n編號,首都爲1號。
  接下來 m行,每行三個整數 abc,表示城市 a和城市 b之間有一條長度爲 c的雙向鐵路。這條鐵路不會通過 ab之外的城市。
輸出格式
  輸出一行,表示在知足條件的狀況下最少要改造的鐵路長度。
樣例輸入
4 5
1 2 4
1 3 5
2 3 2
2 4 3
3 4 2
樣例輸出
11
評測用例規模與約定
  對於20%的評測用例,1 ≤  n ≤ 10,1 ≤  m ≤ 50;
  對於50%的評測用例,1 ≤  n ≤ 100,1 ≤  m ≤ 5000;
  對於80%的評測用例,1 ≤  n ≤ 1000,1 ≤  m ≤ 50000;
  對於100%的評測用例,1 ≤  n ≤ 10000,1 ≤  m ≤ 100000,1 ≤  ab ≤ n,1 ≤  c ≤ 1000。輸入保證每一個城市均可以經過鐵路達到首都。
 
分析:
題意就是求1到全部點的最短路,而且記錄這些路徑
求最短路就是dijkstra算法,在算法過程當中記錄到達節點i的一條最優邊,這樣共獲得n-1條邊,也就是最終的結果
一個細節: 當dist[i]==dist[now]+weight時 要更新邊,由於此時的邊權<=以前的邊權.換句話說:重用了一部分邊,減少了最終的邊權和
 
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4+10;
int n,m,a,b,c,num,cnt;
const int INF = 1e9+7;
int head[maxn];
typedef pair<int,int>P;
priority_queue<P,vector<P>,greater<P> >priq;

int vis[maxn];
P dist[maxn];       // edge pos + weight

struct edge
{
    int to,weight,nxt;
    edge(){}
    edge(int a,int b,int c) {to=a;weight=b;nxt=c;}
}e[maxn*20];


void dijkstra()
{
    priq.push(P(0,1));
    dist[1] = P(0,0);      // watch out!
    while(!priq.empty())
    {
        P ho = priq.top();
        priq.pop();

        int now = ho.second;
        if(vis[now]) continue;
        vis[now]=1;
        for(int i=head[now];i;i=e[i].nxt)
        {
            int to = e[i].to,weight=e[i].weight;
            if(!vis[to]){
                if(dist[now].second+weight<=dist[to].second){
                    dist[to] =  P(i,dist[now].second+weight);
                    priq.push(P(dist[to].second,to));
                }
            }
        }
    }
}


int main()
{
    cnt=1;
    memset(head,0,sizeof(head));
    memset(vis,0,sizeof(vis));

    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        dist[i].second=INF;
    }
    while(m--)
    {
        cin>>a>>b>>c;
        e[cnt] = edge(b,c,head[a]);
        head[a] = cnt++;
        e[cnt] = edge(a,c,head[b]);
        head[b] = cnt++;

    }

    dijkstra();
    int tot=0;
    for(int i=2;i<=n;i++)
    {
        int pos=dist[i].first;
        tot+=e[pos].weight;
    }
    cout<<tot<<endl;
    return 0;
}
相關文章
相關標籤/搜索