CCF 交通规划
来源:互联网 发布:crm系统源码 编辑:程序博客网 时间:2024/04/29 04:47
题意大致如下:给你一张无向带权图,有标号为1到n的节点,现在要你选择一些边留下来,使得在留下来的边构成的新的图里,每个节点到节点1的最小距离不变(即和初始图一样),在满足上述要求的前提下,要使留下来的边的权重和最小,并求出这个最小权重和。
题解:只要我们用dijsktra算法加以改造遍历一遍原图,就能解决这个问题。而本题与一般的dijsktra模板题不同的地方在于,一般dijsktra只是求出源点到其他个点的最短距离,但并不考虑和记录路径,但本题要求的是权重和的最小值,也就是说我们要知道的是最后我们选择了哪些边留下来,或者说我们要知道留下来的所有边的权重是多少。为此,我建立了一个结构体叫Node,它有成员dist和cost,dist是表示它到源点的最小距离,而cost是表示为了使它和源点联通的最小花费(这个联通要保证是最短距离的前提下)。至于更新,dist更新和正常dijsktra更新时一样,先找到一个目前没有被加入集合的dist最小的节点u,然后用u来更新周边节点的dist,cost更新则是随着dist的更新进行的(如此保证这个cost满足最小距离这个前提),并且这个cost应该就等于节点u和被更新节点v的边的权重,即有Node[v].cost=weight[u][v]。最后,要注意的就是,有些节点的最短路径可能不止一条,而且,这些节点被开始的u节点更新得到的cost会要比后面的u节点更新得到的cost要大,所以当有Node[v].dist==Node[u].dist+weight[u][v]时,要注意更新Node[v].cost。(根据题目范围,dijkstra算法应用优先队列进行优化)
输入: 两个整数n,m。n是节点数,m是边数。就下来m行,每行三个数u,v,w,代表节点u,v之间有一条权重为w的边。
输出:一个整数,最小权重和。
代码如下:
#include<iostream>#include<cmath>#include<cstdio>#include<cstring>#include<string>#include<queue>using namespace std;const int maxn=10100;const int maxm=101010;const int inf=0x08080808;int n,m;int head[maxn],icount,vis[maxn];struct Edge{ int v,w; int next;}edge[maxm*2];struct Node{ int dist; int cost;}node[maxn];struct Dist{ int dist; int num; bool operator <(const Dist& a)const { return dist>a.dist; }};priority_queue<Dist> pq;void insert_edge(int u,int v,int w){ edge[icount].v=v; edge[icount].w=w; edge[icount].next=head[u]; head[u]=icount++;}void Dij(int s){ for(int i=1;i<=n;++i){ node[i].dist=node[i].cost=inf; vis[i]=0; } Dist temp={0,s}; node[s].dist=node[s].cost=0; pq.push(temp); for(int i=1;i<n;++i){ temp=pq.top(); while(vis[temp.num]){ pq.pop(); temp=pq.top(); } s=temp.num; for(int j=head[s];j!=-1;j=edge[j].next){ int v=edge[j].v,w=edge[j].w; if((node[s].dist+w)<=node[v].dist){ node[v].dist=node[s].dist+w; temp.num=v; temp.dist=node[v].dist; pq.push(temp); if(w<node[v].cost) node[v].cost=w; } } vis[s]=1; }}int main(){ int u,v,w; icount=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) head[i]=-1; for(int i=0;i<m;++i){ scanf("%d%d%d",&u,&v,&w); insert_edge(u,v,w); insert_edge(v,u,w); } Dij(1); int ans=0; for(int i=1;i<=n;++i){ ans+=node[i].cost; } printf("%d\n",ans); return 0;}
- CCF-交通规划
- CCF交通规划
- CCF 交通规划
- ccf 交通规划
- ccf交通规划
- CCF交通规划
- CCF 交通规划
- ccf 交通规划
- CCF-20160904-交通规划
- ccf 交通规划
- CCF 201612-4 交通规划
- CCF 201609-4 交通规划
- CCF 201612-4 交通规划
- 第八次ccf-交通规划
- CCF-交通规划-dijkstra+贪心
- ccf 201609-4交通规划
- ccf 之交通规划 java版
- CCF 201612-4 交通规划(spfa)
- ssm框架学习---mybatis中处理一对一对应关系
- 简述单片机
- 第16周 学生成绩处理2.0
- webpack的使用和vue.js的初次尝试
- IT大牛博客
- CCF 交通规划
- iOS开发-- iOS UIAppearance初见
- CentOS7 开启端口
- USB设备驱动程序-USB Gadget Driver(二)
- fstream类读取UTF-8、Unicode和ANSI文本文档乱码问题的解决方案
- 关于Build Active Architecture Only属性
- 360早期壳的脱壳步骤
- Android应用开发之所有动画使用详解
- USB设备驱动程序-USB Gadget Driver(三)