LA 4080 战争和物流(最短路树)
https://vjudge.net/problem/UVALive-4080
题意:
给出一个n个结点m条边的无向图,每条边上有一个正权。令c等于每对结点的最短路长度之和。不连通的两点的最短路长度视为L。
求出初始时的最短路长度之和以及删除一条边后最大的最短路长度之和。
思路:
最短路树其实很简单,就是用一个二维数组记录某个源点出发所经过的边,如$belong[s][i]$就说明源点s出发经过了i这条边。这样做的好处是当我们枚举删除的边的时候,如果它不在当前源点的最短路树上,那么对于最短路不会有影响,如果在,那么此时就要重新跑最短路。这样可以节约很多时间。
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #include<cstdio>
- #include<vector>
- #include<stack>
- #include<queue>
- #include<cmath>
- #include<map>
- #include<set>
- #include<bitset>
- using namespace std;
- typedef long long ll;
- typedef pair<int,int> pll;
- const ll INF = (ll)<<;
- const int maxn=+;
- int n,m,tot,l;
- ll ans;
- int head[maxn];
- bool vis[maxn],del[],belong[maxn][];
- ll d[maxn],w[maxn];
- int p[maxn];
- struct node
- {
- int id,v,d,next;
- }e[maxn*maxn];
- struct HeapNode
- {
- int u; ll d;
- HeapNode(int u, ll d):u(u),d(d){}
- bool operator<(const HeapNode& rhs) const
- {
- return d>rhs.d;
- }
- };
- void addEdge(int id, int u, int v, int d)
- {
- e[tot].id=id;
- e[tot].d=d;
- e[tot].v=v;
- e[tot].next=head[u];
- head[u]=tot++;
- }
- void dijkstra1(int s)
- {
- priority_queue<HeapNode> Q;
- memset(vis,false,sizeof(vis));
- for(int i=;i<=n;i++) d[i]=INF;
- d[s]=;
- Q.push(HeapNode(s,));
- while(!Q.empty())
- {
- HeapNode x=Q.top(); Q.pop();
- int u=x.u;
- if(vis[u]) continue;
- belong[s][p[u]]=true;
- vis[u]=true;
- for(int i=head[u];i!=-;i=e[i].next)
- {
- int v=e[i].v;
- if(d[v]>d[u]+e[i].d)
- {
- d[v]=d[u]+e[i].d;
- p[v]=e[i].id;
- Q.push(HeapNode(v,d[v]));
- }
- }
- }
- for(int i=;i<=n;i++)
- {
- if(d[i]==INF)
- {
- w[s]+=l;
- ans+=l;
- }
- else
- {
- w[s]+=d[i];
- ans+=d[i];
- }
- }
- }
- ll dijkstra2(int s)
- {
- priority_queue<HeapNode> Q;
- memset(vis,false,sizeof(vis));
- for(int i=;i<=n;i++) d[i]=INF;
- d[s]=;
- Q.push(HeapNode(s,));
- while(!Q.empty())
- {
- HeapNode x=Q.top(); Q.pop();
- int u=x.u;
- if(vis[u]) continue;
- vis[u]=true;
- for(int i=head[u];i!=-;i=e[i].next)
- {
- int v=e[i].v;
- if(del[e[i].id]) continue;
- if(d[v]>d[u]+e[i].d)
- {
- d[v]=d[u]+e[i].d;
- Q.push(HeapNode(v,d[v]));
- }
- }
- }
- ll tmp=;
- for(int i=;i<=n;i++)
- {
- if(d[i]==INF) tmp+=l;
- else tmp+=d[i];
- }
- return tmp;
- }
- int main()
- {
- //freopen("in.txt","r",stdin);
- while(~scanf("%d%d%d",&n,&m,&l))
- {
- tot=;
- memset(head,-,sizeof(head));
- memset(del,false,sizeof(del));
- memset(belong,false,sizeof(belong));
- memset(w,,sizeof(w));
- for(int i=;i<=m;i++)
- {
- int u,v,w;
- scanf("%d%d%d",&u,&v,&w);
- addEdge(i,u,v,w);
- addEdge(i,v,u,w);
- }
- ans=;
- for(int i=;i<=n;i++) dijkstra1(i);
- printf("%lld ",ans);
- ans=;
- for(int i=;i<=m;i++)
- {
- ll tmp=;
- del[i]=true;
- for(int j=;j<=n;j++)
- {
- if(belong[j][i]) tmp+=dijkstra2(j);
- else tmp+=w[j];
- }
- del[i]=false;
- ans=max(ans,tmp);
- }
- printf("%lld\n",ans);
- }
- return ;
- }
LA 4080 战争和物流(最短路树)的更多相关文章
- UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)
题意: 给一个无向图,n个点,m条边,可不连通,可重边,可多余边.两个问题,第一问:求任意点对之间最短距离之和.第二问:必须删除一条边,再求第一问,使得结果变得更大. 思路: 其实都是在求最短路的过程 ...
- 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)
layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...
- UVALive 4080 Warfare And Logistics (最短路树)
很多的边会被删掉,需要排除一些干扰进行优化. 和UVA - 1279 Asteroid Rangers类似,本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路 ...
- hdu 3409 最短路树+树形dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3409 参考博客:http://www.cnblogs.com/woaishizhan/p/318981 ...
- LA4080/UVa1416 Warfare And Logistics 最短路树
题目大意: 求图中两两点对最短距离之和 允许你删除一条边,让你最大化删除这个边之后的图中两两点对最短距离之和. 暴力:每次枚举删除哪条边,以每个点为源点做一次最短路,复杂度\(O(NM^2logN)\ ...
- BZOJ1975[Sdoi2010]魔法猪学院——可持久化可并堆+最短路树
题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...
- BZOJ4356Ceoi2014 Wall——堆优化dijkstra+最短路树
题目描述 给出一个N*M的网格图,有一些方格里面存在城市,其中首都位于网格图的左上角.你可以沿着网络的边界走,要求你走的路线是一个环并且所有城市都要被你走出来的环圈起来,即想从方格图的外面走到任意一个 ...
- 51nod 1443 路径和树(最短路树)
题目链接:路径和树 题意:给定无向带权连通图,求从u开始边权和最小的最短路树,输出最小边权和. 题解:构造出最短路树,把存留下来的边权全部加起来.(跑dijkstra的时候松弛加上$ < $变成 ...
- Berland and the Shortest Paths CodeForces - 1005F(最短路树)
最短路树就是用bfs走一遍就可以了 d[v] = d[u] + 1 表示v是u的前驱边 然后遍历每个结点 存下它的前驱边 再用dfs遍历每个结点 依次取每个结点的某个前驱边即可 #include &l ...
随机推荐
- 【剑指offer】包含min函数的栈
一.题目: 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数. 二.思路: 无,Z(zhi)Z(zhang)式操作. 三.代码:
- ubuntu 下执行定时任务
Window shell文件在linux系统下执行不了的解决办法 一些人喜欢用vim来写linux shell script, 但是, 有的人喜欢在Windows下用一些方便的编辑器(比如鼎鼎大名的N ...
- HTML5-CSS3-JavaScript(2)
我们就从HTML5的基础总结起.希望可以提高自身的基础. HTML5 新增的通用属性 1. contentEditable 属性 HTML5 为大部分HTML元素都增加了contentEditable ...
- Selenium - Xpath 使用方法
由于最新版火狐不在支持FireBug等开发工具,可以通过https://ftp.mozilla.org/pub/firefox/releases/下载49版本以下的火狐就可以增加Firebug等扩展了 ...
- python-计算器实现
# 开发一个简单的python计算器# 实现加减乘除及括号优先级解析# 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- uva1201 DAG 最小路径覆盖,转化为 二分图
大白例题P356 你在一座城市里负责一个大型活动的接待工作.你需要去送m个人从出发地到目的地,已知每个人的出发时间出发地点,和目的地点,你的任务是用尽量少的出租车送他们,使得每次出租车接客人,至少能提 ...
- Python: 合并多个字典
现在有多个字典或者映射,想将它们从逻辑上合并为一个单一的映射后执行某些操作,比如查找值或者检查某些键是否存在. eg1: a = {'x': 1, 'z': 3 }b = {'y': 2, 'z': ...
- centos 网卡名称修改
在centos6.4之前,如果6.2,6.3安装后网卡名称都是em开始,如果想用eth0这种名称,或者是自定义名称,可以参照以下来实施. 第一步:修改/boot/grub/grub.conf增加一个 ...
- 音响理论基础入门:Gain(增益)
谈到放大器就必须先了解增益:一个小的信号Level(电平)经过放大电路成为大的信号Level ,也就是说由小变大之间的差异就叫增益,也叫放大率,反过来的叫衰减率.在音响系统内,一般以信号源的输入电平决 ...