CCF 201609-4 交通规划(dij变形)
问题描述
试题编号: | 201609-4 |
试题名称: | 交通规划 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。 输入格式 输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。 输出格式 输出一行,表示在满足条件的情况下最少要改造的铁路长度。 样例输入 4 5 样例输出 11 评测用例规模与约定 对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50;
|
题意大致就是给你一个铁路网络,然后要求你改造最少的铁路,以至于从所有城市乘坐高速铁路到首都的最短路程和原来一样长,这题就是用迪杰斯特拉跑个最短路,在求到每个点的最短路的同时维护cost[u]即起点到u节点的最短路所对应要改造的最少的铁路。
#include<bits/stdc++.h>
using namespace std;
#define inf 100000000+5
struct edge
{
int v,w,nxt;
edge(int vv=0,int ww=0,int nxtt=0)
{
v=vv;
w=ww;
nxt=nxtt;
}
}e[200000+10];
struct node
{
int v,w;
node(int vv=0,int ww=0)
{
v=vv;
w=ww;
}
friend bool operator<(const node&a,const node&b)
{
return a.w>b.w;
}
};
int dis[10000+10],head[10000+10],cost[10000+10],vis[10000+10],n,m;//就比普通的dij多了个cost数组
void dij()
{
for(int i=1;i<=n;i++)
dis[i]=inf,vis[i]=0;
dis[1]=0;
cost[1]=0;
priority_queue<node>q;
while(!q.empty()) q.pop();
q.push(node(1,dis[1]));
while(!q.empty())
{
int u=(q.top()).v;
q.pop();
if(!vis[u])
{
vis[u]=1;
for(int i=head[u];i!=-1;i=e[i].nxt)
{
int v=e[i].v,w=e[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
cost[v]=w;//表示到v的最短路对应要改造的铁路的最短长度为w,即u到v这条边的边权,因为起点到u的最短路所要改造的最短长度已经加在了u及其前面的点的cost值里了
q.push(node(v,dis[v]));
}
else
if((dis[v]==dis[u]+w)&&w<cost[v])//这种情况要注意
cost[v]=w;
}
}
}
}
int main()
{
memset(head,-1,sizeof(head));
int cnt=0,ans=0;;
scanf("%d %d",&n,&m);
while(m--)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
e[cnt]=edge(v,w,head[u]);
head[u]=cnt++;
e[cnt]=edge(u,w,head[v]);
head[v]=cnt++;
}
dij();
for(int i=2;i<=n;i++) ans+=cost[i];
cout<<ans<<endl;
return 0;
}