UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)
题意:
给一个无向图,n个点,m条边,可不连通,可重边,可多余边。两个问题,第一问:求任意点对之间最短距离之和。第二问:必须删除一条边,再求第一问,使得结果变得更大。
思路:
其实都是在求最短路的过程。
第一问可以floyd解决,也可以SSSP解决。注意是任意两个点,(a,b)和(b,a)是不同的,都要算。
第二问要穷举删除每条边,再求第一问。为了降低复杂度,假设用dijkstra求最短路,那么可以利用第一问中所生成的树,共n棵,每棵至多n-1条边,如果穷举的边不在该某树上,那么该树的所有路径长不变,不必计算,否则需要计算。所以需要记录路径,并将整棵树的边集存起来,同时保存每棵树的任意两点路径之和。
用结构体可以解决重边,问题应该不多,要注意各种细节,错了就重新打,也许更快。
#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=;
int n, m, l, edge_cnt;
vector<int> vect[N]; struct node
{
int from, to, dis,tag;
node(){};
node(int from,int to,int dis,int tag):from(from),to(to),dis(dis),tag(tag){};
}edge[]; void add_node(int from,int to,int dis,int tag)
{
edge[edge_cnt]=node(from, to, dis, tag);
vect[from].push_back(edge_cnt++);
} int dist[N], vis[N], path[N];
LL dijkstra(int s)
{
memset(dist,0x7f,sizeof(dist));
memset(vis,,sizeof(vis));
for(int i=; i<=n; i++) path[i]=-; priority_queue<pii,vector<pii>,greater<pii> > que;
dist[s]=;
que.push(make_pair(,s)); while(!que.empty())
{
int x=que.top().second;que.pop();
if(vis[x]) continue;
vis[x]=;
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if(e.tag> && dist[e.to]>dist[e.from]+e.dis )
{
path[e.to]=vect[x][i];
dist[e.to]=dist[e.from]+e.dis;
que.push(make_pair(dist[e.to], e.to));
}
}
} LL sum=;
for(int i=; i<=n; i++ )
{
if(dist[i]>=INF) sum+=l;//不可达的,按L算
else sum+=dist[i];
}
return sum;
} LL ans1[N];
int cal()
{
memset(ans1,,sizeof(ans1));
LL first=;
unordered_set<int> tree[N];
for(int i=; i<=n; i++)
{
ans1[i]=dijkstra(i);
first+=ans1[i];
//收集边
for(int k=; k<=n; k++)
{
if(path[k]>=)//注意如何初始化
{
tree[i].insert(path[k]);
tree[i].insert(path[k]^);
}
}
}
//另一个问
LL second=;
for(int i=; i<edge_cnt; i+=)
{
edge[i].tag=edge[i+].tag=;
LL sum=;
for(int j=; j<=n; j++)
{
if( tree[j].find(i)==tree[j].end() ) //是点j的树上,要重新算
sum+=ans1[j];
else
sum+=dijkstra(j);
}
second=max(second, sum);
edge[i].tag=edge[i+].tag=;
}
printf("%lld %lld\n", first, second );//仅1个空格
} int main()
{
freopen("input.txt", "r", stdin);
int a, b, c;
while(scanf("%d%d%d", &n, &m, &l)==)
{
edge_cnt=;
memset(edge,,sizeof(edge));
for(int i=; i<=n; i++) vect[i].clear();
for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
if(a==b) continue;
add_node(a,b,c,);
add_node(b,a,c,);
}
cal();
}
return ;
}
AC代码
UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)的更多相关文章
- 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)
layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...
- UVALive 4080 Warfare And Logistics (最短路树)
很多的边会被删掉,需要排除一些干扰进行优化. 和UVA - 1279 Asteroid Rangers类似,本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路 ...
- uva 1416 Warfare And Logistics
题意: 给出一个无向图,定义这个无向图的花费是 其中path(i,j),是i到j的最短路. 去掉其中一条边之后,花费为c’,问c’ – c的最大值,输出c和c’. 思路: 枚举每条边,每次把这条边去掉 ...
- UVA - 1416 Warfare And Logistics (最短路)
Description The army of United Nations launched a new wave of air strikes on terroristforces. The ob ...
- UVA1416 Warfare And Logistics
UVA1416 Warfare And Logistics 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36232 [ ...
- LA 4080 战争和物流(最短路树)
https://vjudge.net/problem/UVALive-4080 题意:给出一个n个结点m条边的无向图,每条边上有一个正权.令c等于每对结点的最短路长度之和.不连通的两点的最短路长度视为 ...
- Warfare And Logistics UVA - 1416
题目链接:https://vjudge.net/problem/UVA-1416 题解: 这是一个最短路的好题,首先我们考虑如果暴力弗洛伊德,显然时间复杂度不对,如果做n次spfa好像复杂度也不对,所 ...
- 【UVA1416】(LA4080) Warfare And Logistics (单源最短路)
题目: Sample Input4 6 10001 3 21 4 42 1 32 3 33 4 14 2 2Sample Output28 38 题意: 给出n个节点m条无向边的图,每条边权都为正.令 ...
- LA4080/UVa1416 Warfare And Logistics 最短路树
题目大意: 求图中两两点对最短距离之和 允许你删除一条边,让你最大化删除这个边之后的图中两两点对最短距离之和. 暴力:每次枚举删除哪条边,以每个点为源点做一次最短路,复杂度\(O(NM^2logN)\ ...
随机推荐
- jquery常用函数与方法汇总
1.delay(duration,[queueName]) 设置一个延时来推迟执行队列中之后的项目. jQuery1.4新增.用于将队列中的函数延时执行.他既可以推迟动画队列的执行,也可以用于自定义队 ...
- BZOJ 4341 [CF253 Printer] 解题报告
乍一看这个题好像可以二分优先度搞搞... 实际上能不能这么搞呢...? 我反正不会... 于是开始讲我的乱搞算法: 首先肯定要把任务按照优先度排序. 用一棵在线建点的线段树维护一个时刻是否在工作. 然 ...
- 循环队列实现(C++) Ring Buffer
循环队列:队列有着先入先出的特性.但是对于队列如果删除队头以后剩下的空间将不会被释放,又由于队列只能由队尾插入这就导致被删除部分的空间被浪费.解决这个问题就是循环队列.循环队列顾名思义就是将队列串起来 ...
- Unity3D角色攻击范围判定和攻击判定
原地址:http://www.unity蛮牛.com/blog-1801-479.html 第一种方法:运用点乘 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 ...
- timeit统计运行时间
import timeitt1 = timeit.timeit('sum(x*x for x in xrange(10000))',number = 10000) print t1
- DataGridView之行的展开与收缩
很多数据都有父节点与子节点,我们希望单击父节点的时候可以展开父节点下的子节点数据. 比如一个医院科室表,有父科室与子科室,点击父科室后,在父科室下面可以展现该科室下的所有子科室. 我们来说一下在Dat ...
- Java Excel
http://www.cnblogs.com/mingforyou/archive/2013/08/26/3282922.html
- sun.misc.unsafe类的使用
http://blog.csdn.net/fenglibing/article/details/17138079
- lintcode :Trailing Zeros 尾部的零
题目: 尾部的零 设计一个算法,计算出n阶乘中尾部零的个数 样例 11! = 39916800,因此应该返回 2 挑战 O(logN)的时间复杂度 解题: 常用方法: 也许你在编程之美中看到,通过求能 ...
- 分布式内存对象缓存系统Memcached-Linux下使用
Linux下Memcached的使用 1. 安装文件下载 1.1下载memcached服务器端安装文件 版本: memcached-1.4.2.tar.gz 下载地址:http://www ...