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 ...
随机推荐
- npm设置淘宝镜像
npm config set registry https://registry.npm.taobao.org --global npm config set disturl https://npm. ...
- 什么是anaconda【转载】
转自:https://zhidao.baidu.com/question/525102108723657245.html https://zhidao.baidu.com/question/62475 ...
- 关于Flag的定义
最近在维护项目的代码,发现了由于Flag不一致导致的很多问题,现在对这一问题总结. 1,flag分为两种,可以组合的和不可以组合的.可以组合的flag适合用每一位表示一个含义.不适合组合的flag适合 ...
- Python Pandas找到缺失值的位置
python pandas判断缺失值一般采用 isnull(),然而生成的却是所有数据的true/false矩阵,对于庞大的数据dataframe,很难一眼看出来哪个数据缺失,一共有多少个缺失数据,缺 ...
- pythonon ddt数据驱动二(json, yaml 驱动)
这一篇主要是关于文件的数据驱动. 一.通过json文件驱动 @ddt class MyTest(unittest.TestCase): @file_data('test_data_list.json' ...
- iOS下拉刷新和上拉刷新
在iOS开发中,我们经常要用到下拉刷新和上拉刷新来加载新的数据,当前这也适合分页.iOS原生就带有该方法,下面就iOS自带的下拉刷新方法来简单操作. 上拉刷新 1.在TableView里,一打开软件, ...
- PHP获取http头信息
PHP手册提供了现成的函数: getallheaders (PHP 4, PHP 5) getallheaders — Fetch all HTTP request headers 说明 array ...
- 【转】Linux进程绑CPU核
1. 什么是绑核? 所谓绑核,其实就是设定某个进程/线程与某个CPU核的亲和力(affinity).设定以后,Linux调度器就会让这个进程/线程只在所绑定的核上面去运行.但并不是说该进程/线程就独占 ...
- linux常用命令:tr 命令
tr 命令实现字符转换功能,其功能类似于 sed 命令,但是,tr 命令比 sed 命令简单.也就是说,tr 命令能实现的功能,sed 命令都可以实现.尽管如此,tr 命令依然是 Linux 系统下处 ...
- python 单例模式,一个类只能生成唯一的一个实例,重写__new__方法详解
单例:一个类只能生成唯一的一个实例 每个类只要被实例化了,他的私有属性 '_instance'就会被赋值,这样理解对吗 对 #方法1,实现__new__方法 #并在将一个类的实例绑定到类变量_inst ...