1. 程式人生 > >CCF-交通規劃(最短路變形->dj演算法)

CCF-交通規劃(最短路變形->dj演算法)

問題描述   G國國王來中國參觀後,被中國的高速鐵路深深的震撼,決定為自己的國家也建設一個高速鐵路系統。
  建設高速鐵路投入非常大,為了節約建設成本,G國國王決定不新建鐵路,而是將已有的鐵路改造成高速鐵路。現在,請你為G國國王提供一個方案,將現有的一部分鐵路改造成高速鐵路,使得任何兩個城市間都可以通過高速鐵路到達,而且從所有城市乘坐高速鐵路到首都的最短路程和原來一樣長。請你告訴G國國王在這些條件下最少要改造多長的鐵路。 輸入格式   輸入的第一行包含兩個整數n, m,分別表示G國城市的數量和城市間鐵路的數量。所有的城市由1到n編號,首都為1號。
  接下來m行,每行三個整數a, b, c,表示城市a和城市b之間有一條長度為c的雙向鐵路。這條鐵路不會經過a和b以外的城市。 輸出格式   輸出一行,表示在滿足條件的情況下最少要改造的鐵路長度。 樣例輸入 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 ≤ a, b ≤ n,1 ≤ c ≤ 1000。輸入保證每個城市都可以通過鐵路達到首都。

解題思路:被題目給嚇到了,其實就是簡單的dj演算法,多開一個cost陣列記錄當前點到原點的最少要加的邊的長度(在最短路的前提下)

當遇到當前點到原點的最短路不止一條時,便更新cost陣列,最後將所有點的cost相加即可

#include<stdio.h>
#include<string.h>
#include<limits.h>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 100005
int flag[maxn],cost[maxn],road[maxn];
int n,m;
struct node
{
	int to;
	int cost;
	node(int u,int v)
	{
		to=u;
		cost=v;
	}
};
vector<node>edge[maxn];
void work()
{
	int i,j;
	memset(cost,1,sizeof(cost));
	memset(road,1,sizeof(road));
	for(i=0;i<edge[1].size();i++)
	{
		int v=edge[1][i].to;
		road[v]=edge[1][i].cost;
		cost[v]=edge[1][i].cost;
	}
	road[1]=cost[1]=0;
	flag[1]=1;
	for(i=2;i<=n;i++)
	{
		int c,k=INT_MAX;
		for(j=2;j<=n;j++)
		{
			if(!flag[j] && k>road[j])
			{
				k=road[j];
				c=j;
			}
		}
		flag[c]=1;
		for(j=0;j<edge[c].size();j++)
		{
			int v=edge[c][j].to;
			int temp=edge[c][j].cost;
			if(!flag[v] && temp+road[c]<road[v])
			{
				road[v]=temp+road[c];
				cost[v]=temp;
			}
			else if(!flag[v] && temp+road[c]==road[v])
				cost[v]=min(cost[v],temp);
		}
	}
}
int  main()
{
	int i,j,x,y,z;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		edge[x].push_back(node(y,z));
		edge[y].push_back(node(x,z));
	}
	work();
	int ans=0;
	for(i=2;i<=n;i++)
		ans+=cost[i];
	printf("%d\n",ans);
}