试题编号: | 201609-4 |
试题名称: | 交通规划 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。 输入格式 输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。 输出格式 输出一行,表示在满足条件的情况下最少要改造的铁路长度。 样例输入 4 5 样例输出 11 评测用例规模与约定 对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50; |
问题链接:CCF201609-4 交通规划
问题分析:最短路径,cost[i]存储源点到i的最短路径中到达i的前一个点到点i的距离 ,把所有点的cost[i]加起来就是答案
程序说明:使用dijkstra算法求解最短路径,使用vector存储图的邻接表
提交后得100分的C++程序:
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=10003;
struct Edge{//边
int v,w;//起点到终点v的花费为w
Edge(int v,int w):v(v),w(w){}
};
struct Node{//结点
int u,w;//结点编号为u,源点到此节点的最短路径为w
Node(){}
Node(int u,int w):u(u),w(w){}
bool operator<(const Node &a)const//使用优先队列,故将<重载为大于含义
{
return w>a.w;
}
};
vector<Edge>g[N];//图的邻接表
int dist[N];
int cost[N];//cost[i]存储源点到i的最短路径中到达i的前一个点到点i的距离
void dijkstra(int s,int n)//源点为s,共有n个结点
{
bool vis[N];
memset(vis,false,sizeof(vis));
memset(cost,INF,sizeof(cost));
memset(dist,INF,sizeof(dist));
dist[s]=0;
cost[s]=0;
priority_queue<Node>q;
q.push(Node(s,0));
while(!q.empty()){
Node e=q.top();
q.pop();
int u=e.u;
if(!vis[u]){
vis[u]=true;
int num=g[u].size();//与u相连的点有numge
for(int i=0;i<num;i++){
int v=g[u][i].v;//v为与u相连的点
if(vis[v])
continue;
int c=g[u][i].w;
if(dist[v]>dist[u]+c){
dist[v]=dist[u]+c;
cost[v]=c;
q.push(Node(v,dist[v]));
}
else if(dist[v]==dist[u]+c)//最短路径相同就更新cost
cost[v]=min(cost[v],c);
}
}
}
}
int main()
{
int n,m,a,b,c;
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%d%d",&a,&b,&c);
g[a].push_back(Edge(b,c));
g[b].push_back(Edge(a,c));
}
dijkstra(1,n);
int ans=0;
for(int i=1;i<=n;i++)
ans+=cost[i];
printf("%d\n",ans);
return 0;
}