题目大意:

  • 求图中两两点对最短距离之和

  • 允许你删除一条边,让你最大化删除这个边之后的图中两两点对最短距离之和。

暴力:每次枚举删除哪条边,以每个点为源点做一次最短路,复杂度\(O(NM^2logN)\)。

值得注意的是,\(Dijkstra\)的复杂度\(O(NlogN)\)是关于边而非点的

这个复杂度对于\(n=100,m=1000\)的数据难以接受。我们考虑对每个点建出其最短路树。容易想到,只有删除到这个点的最短路树上的边时,才需要再做一次\(Dijkstra\)。也就是说每个源点只需要做\(n\)次最短路,复杂度变成\(O(N^2MlogN)\)。

代码实现起来比较麻烦。。本弱调了整整一晚上。

#include <bits/stdc++.h>
using namespace std; #define LL long long
const int N = 100 + 5;
const int M = 2000 + 5;
const int INF = 0x3f3f3f3f; int n, m, l, kase, ban[M]; struct Graph { int cnt, head[N]; struct Edge {int from, nxt, to, id, w;}e[M]; void clear () {
cnt = -1;
for (int i = 1; i <= n; ++i) {
head[i] = -1;
}
} void add_edge (int u, int v, int w) {
++cnt; e[cnt] = (Edge) {u, head[u], v, cnt, w}; head[u] = cnt;
} struct HeapNode {
int u; LL d;
bool operator < (HeapNode rhs) const {
return d > rhs.d;
}
}; priority_queue <HeapNode> pq; int done[N], _fa[N][N]; LL _dis[N][N];
//dis[i][j] -> i to j
//fa[i][j] -> i as source, j's father void dijkstra (int s) {
kase = kase + 1;
pq.push ((HeapNode) {s, 0});
LL *dis = _dis[s]; int *fa = _fa[s];
for (int i = 1; i <= n; ++i) {
fa[i] = -1, dis[i] = i == s ? 0 : INF;
}
while (!pq.empty ()) {
HeapNode now = pq.top (); pq.pop ();
if (done[now.u] == kase) continue;
for (int i = head[now.u]; ~i; i = e[i].nxt) {
int v = e[i].to;
if (ban[i]) continue;//禁用的边 -> 不用
if (dis[v] > dis[now.u] + e[i].w) {
fa[v] = now.u;
dis[v] = dis[now.u] + e[i].w;
pq.push ((HeapNode) {v, dis[v]});
}
}
done[now.u] = kase;
}
// cout << "s = " << s << endl;
// for (int i = 1; i <= n; ++i) {
// cout << "dis[" << i << "] = " << dis[i] << endl;
// }
}
}G; bool have[N][M]; int minw[N][N]; struct Tree { vector <int> Gr[N]; int sz[N]; LL sum[N], dis[N]; //sz[u] -> 点u的子树大小
//sum[u] -> 点u到其子树里所有点的距离和 void prep (int u) {
sz[u] = 1; sum[u] = dis[u];
for (int i = 0; i < (int)Gr[u].size (); ++i) {
int v = Gr[u][i];
prep (v);
sz[u] += sz[v];
sum[u] += sum[v];
}
} void build (int s, LL *_dis, int *fa, int cmd) {
for (int i = 1; i <= n; ++i) Gr[i].clear ();
memcpy (dis, _dis, sizeof (dis));
for (int i = 1; i <= n; ++i) {
if (fa[i] != -1) {
Gr[fa[i]].push_back (i);
if (cmd == 1) {
have[fa[i]][i] = true;
have[i][fa[i]] = true;
}
}
}
prep (s);
// for (int i = 1; i <= n; ++i) {
// cout << "dis[" << i << "] = " << dis[i] << endl;
// cout << "sum[" << i << "] = " << sum[i] << endl;
// }
} LL get_ans (int s, LL *_dis, int *fa, int cmd) {
build (s, _dis, fa, cmd);
return sum[s] + (n - sz[s]) * l;
} }tr[N];//tr[i] -> 点i的最短路树 signed main () {
// freopen ("data.in", "r", stdin);
// freopen ("data.out", "w", stdout);
while (cin >> n >> m >> l) {
G.clear ();
memset (have, 0, sizeof (have));
memset (minw, 0x3f, sizeof (minw));
for (int i = 1; i <= m; ++i) {
static int u, v, w;
cin >> u >> v >> w;
G.add_edge (u, v, w);
G.add_edge (v, u, w);
minw[u][v] = min (minw[u][v], w);
minw[v][u] = min (minw[v][u], w);
}
LL ans1 = 0, ans2 = 0;
for (int s = 1; s <= n; ++s) {
G.dijkstra (s);
ans1 += tr[s].get_ans (s, G._dis[s], G._fa[s], 1);
//存一下最初的have
}
cout << ans1 << " ";
for (int i = 0; i <= G.cnt; i += 2) {
//每次枚举禁用一条边。
LL res_now = 0;
ban[i] = ban[i + 1] = true;//双向都要禁
for (int s = 1; s <= n; ++s) { //枚举删除之后每一棵最短路树的状况
int u = G.e[i].from, v = G.e[i].to, w = G.e[i].w;
if (have[u][v] && w == minw[u][v]) G.dijkstra (s);
res_now += tr[s].get_ans (s, G._dis[s], G._fa[s], 0);
}
ban[i] = ban[i + 1] = false;
ans2 = max (ans2, res_now);
}
cout << ans2 << endl;
}
}

LA4080/UVa1416 Warfare And Logistics 最短路树的更多相关文章

  1. UVA1416 Warfare And Logistics

    UVA1416 Warfare And Logistics 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36232 [ ...

  2. UVA1416/LA4080 Warfare And Logistics

    题目大意:有N个点,M条路,如果两条路不连通的话,就将这两条路的距离设置为L 现在要求你求出每两点之间的最短距离和 接着要求 求出炸断 给出的M条路中的一条路后,每两点之间的最短距离和的最大值(翻译来 ...

  3. 【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条无向边的图,每条边权都为正.令 ...

  4. UVALive 4080 Warfare And Logistics (最短路树)

    很多的边会被删掉,需要排除一些干扰进行优化. 和UVA - 1279 Asteroid Rangers类似,本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路 ...

  5. la4080 Warfare And Logistics 罗列+最短

    为了图.计算最短随机分ans1.和删除边缘.免费才能够获得最大和短路之间的最大分ans2,如果这两个不沟通.看作是两个点之间的最短距离l. 第一个想法是枚举每个边缘,然后运行n最短时间.但是,这种复杂 ...

  6. 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

    layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...

  7. Warfare And Logistics UVA - 1416

    题目链接:https://vjudge.net/problem/UVA-1416 题解: 这是一个最短路的好题,首先我们考虑如果暴力弗洛伊德,显然时间复杂度不对,如果做n次spfa好像复杂度也不对,所 ...

  8. hdu 3409 最短路树+树形dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3409 参考博客:http://www.cnblogs.com/woaishizhan/p/318981 ...

  9. BZOJ1975[Sdoi2010]魔法猪学院——可持久化可并堆+最短路树

    题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...

随机推荐

  1. css 修改默认滚动条样式

    来自:https://www.cnblogs.com/juqian/p/6273808.html 侵删 <div class="inner"> <div clas ...

  2. java工作流引擎Jflow父子流程demo

    关键字 驰骋工作流引擎 流程快速开发平台 workflow ccflow jflow  .net开源工作流 定义 一个流程A的一个节点,因工作的需要调起另外的流程B,A就叫父流程,B就叫子流程.如果流 ...

  3. 属于自己的MES(二)必备的主数据

    MES在系统建设前,需要先进行一些必要的数据,这些主数据是支撑MES执行的关键. 1.BOM BOM通常称为“物料清单”,也就是产品结构,在化工.制药.食品.烟草领域也叫“配方”,它主要描述了物料的物 ...

  4. packagereference 里面的资产是怎么回事?

    <PackageReference Include="Newtonsoft.Json" Version="9.0.1"> <ExcludeAs ...

  5. TCP点对点转发的实现与原理(nodejs)

    Nagent Nagent是TCP点对点转发实现,名称来源于Nat与Agent的组合.类似frp项目,可以在局域网与互联网提供桥梁. 前提是你要有一台流量服务器并且有一个公网IP.如果没有,也可以找服 ...

  6. DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery

    这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...

  7. activemq读取剩余消息队列中消息的数量

    先上原文链接: http://blog.csdn.net/bodybo/article/details/5647968  ActiveMQ在C#中的应用 ActiveMQ是个好东东,不必多说.Acti ...

  8. Oracle 安装步骤、安装中错误处理、完整卸载

    /*************************************************以下ORACLE服务端安装************************************* ...

  9. jupyter notebook修改默认路径和浏览器

    1.jupyter notebook --generate-config 2.修改jupyter_notebook_config.py配置文件 3.修改默认路径: c.NotebookApp.note ...

  10. 获取Iframe页面高度并赋值给Iframe以及获取iframe里的元素

    最近接手了别人的项目,别人用到了iframe,自己在实战中总结了一些关于iframe的小问题. 获取Iframe页面高度并赋值给Iframe Html <iframe name="co ...