您的位置:首页 > 其它

CCF 201612-4 交通规划(spfa)

2016-12-01 13:07 281 查看
问题描述
  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

思路:由于要求最短路不变,我们要从点1直接跑spfa求出最短路,然后跑的过程中记录每个节点的最短前驱就好。长时间不打比赛脑子都有点不好使了…刚开始写成了酱:

if (dis[v]>dis[h]+w) {
pre[v]=min(pre[v],w);
dis[v]=dis[h]+w;
if (!vis[v]) {
vis[v]=1;
q.push(v);
}
} else if(dis[v]==dis[h]+w)
pre[v]=min(pre[v],w);

后来怎么都错,然后看了看别人思路改过来了,首先要以最短路为主,然后求最小值T_T。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include<algorithm>
#include<queue>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
const int INF=1000000000,N=1000000;///N表示点的最多数量
int head
,dis
;
bool vis
;
int ip;
struct data {
int to,next,w;
} tu[N*10];
void init() {
ip=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w) {
tu[ip].to=v,tu[ip].w=w,tu[ip].next=head[u],head[u]=ip++;
}
int pre
;
void spfa(int s,int n) {
queue<int>q;
for (int i=0; i<=n; i++)
dis[i]=pre[i]=INF;
memset(vis,0,sizeof(vis));
q.push(s);
dis[s]=0;
while(!q.empty()) {
int h=q.front();
q.pop();
vis[h]=0;
for (int i=head[h]; i!=-1; i=tu[i].next) {
int v=tu[i].to;
int w=tu[i].w;
if (dis[v]>dis[h]+w) {
pre[v]=w;
dis[v]=dis[h]+w;
if (!vis[v]) {
vis[v]=1;
q.push(v);
}
} else if(dis[v]==dis[h]+w)
pre[v]=min(pre[v],w);
}
}
}
int main(int argc, char** argv) {
init();
int n,m;
cin>>n>>m;
for(int i=0; i<m; i++) {
int a,b,w;
cin>>a>>b>>w;
add(a,b,w);
add(b,a,w);
}
spfa(1,n);
int ans=0;
for(int i=2; i<=n; i++)
ans+=pre[i];
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm ccf