大白书P330 这题比较麻烦

给出一个n个节点m条边的无向图,每条边上有一个正权。令c等于每对节点的最短路长度之和。例n=3时, c = d(1,1)+d(1,2)+d(1,3)+d(2,1)+d(2,2)+d(2,3)+d(3,1)+d(3,2)+d(3,3);

要求删除一条边后使得新的c值c‘最大。不连通的两点的最短路径长度为L

// LA4080/UVa1416 Warfare And Logistics
// Rujia Liu
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std; const int INF = ;
const int maxn = + ; struct Edge {
int from, to, dist;
}; struct HeapNode {
int d, u;
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
}; struct Dijkstra {
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn]; // 是否已永久标号
int d[maxn]; // s到各个点的距离
int p[maxn]; // 最短路中的上一条弧 void init(int n) {
this->n = n;
for(int i = ; i < n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int dist) {
edges.push_back((Edge){from, to, dist});
m = edges.size();
G[from].push_back(m-);
} void dijkstra(int s) {
priority_queue<HeapNode> Q;
for(int i = ; i < n; i++) d[i] = INF;
d[s] = ;
memset(done, , sizeof(done));
Q.push((HeapNode){, s});
while(!Q.empty()) {
HeapNode x = Q.top(); Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i = ; i < G[u].size(); i++) {
Edge& e = edges[G[u][i]];
if(e.dist > && d[e.to] > d[u] + e.dist) { // 此处和模板不同,忽略了dist=-1的边。此为删除标记。根据题意和dijkstra算法的前提,正常的边dist>0
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push((HeapNode){d[e.to], e.to});
}
}
}
}
}; //////// 题目相关
Dijkstra solver;
int n, m, L;
vector<int> gr[maxn][maxn]; // 两点之间的原始边权
int used[maxn][maxn][maxn]; // used[src][a][b]表示源点为src的最短路树是否包含边a->b
int idx[maxn][maxn]; // idx[u][v]为边u->v在Dijkstra求解器中的编号
int sum_single[maxn]; // sum_single[src]表示源点为src的最短路树的所有d之和 int compute_c() {
int ans = ;
memset(used, , sizeof(used));
for(int src = ; src < n; src++) {
solver.dijkstra(src);
sum_single[src] = ;
for(int i = ; i < n; i++) {
if(i != src) {
int fa = solver.edges[solver.p[i]].from;
used[src][fa][i] = used[src][i][fa] = ;
}
sum_single[src] += (solver.d[i] == INF ? L : solver.d[i]);
}
ans += sum_single[src];
}
return ans;
} int compute_newc(int a, int b) {
int ans = ;
for(int src = ; src < n; src++)
if(!used[src][a][b]) ans += sum_single[src];
else {
solver.dijkstra(src);
for(int i = ; i < n; i++)
ans += (solver.d[i] == INF ? L : solver.d[i]);
}
return ans;
} int main() {
while(scanf("%d%d%d", &n, &m, &L) == ) {
solver.init(n);
for(int i = ; i < n; i++)
for(int j = ; j < n; j++) gr[i][j].clear(); for(int i = ; i < m; i++) {
int a, b, s;
scanf("%d%d%d", &a, &b, &s); a--; b--;
gr[a][b].push_back(s);
gr[b][a].push_back(s);
} // 构造网络
for(int i = ; i < n; i++)
for(int j = i+; j < n; j++) if(!gr[i][j].empty()) {
sort(gr[i][j].begin(), gr[i][j].end());
solver.AddEdge(i, j, gr[i][j][]);
idx[i][j] = solver.m - ;
solver.AddEdge(j, i, gr[i][j][]);
idx[j][i] = solver.m - ;
} int c = compute_c();
int c2 = -;
for(int i = ; i < n; i++)
for(int j = i+; j < n; j++) if(!gr[i][j].empty()) {
int& e1 = solver.edges[idx[i][j]].dist;
int& e2 = solver.edges[idx[j][i]].dist;
if(gr[i][j].size() == ) e1 = e2 = -;
else e1 = e2 = gr[i][j][]; // 大二短边
c2 = max(c2, compute_newc(i, j));
e1 = e2 = gr[i][j][]; // 恢复
} printf("%d %d\n", c, c2);
}
return ;
}

uva1416 dijkstra的更多相关文章

  1. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  2. 最短路径算法-Dijkstra

    Dijkstra是解决单源最短路径的一般方法,属于一种贪婪算法. 所谓单源最短路径是指在一个赋权有向图中,从某一点出发,到另一点的最短路径. 以python代码为例,实现Dijkstra算法 1.数据 ...

  3. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  4. POJ 2253 Frogger(Dijkstra)

    传送门 Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 39453   Accepted: 12691 Des ...

  5. POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)

    传送门 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46727   Acce ...

  6. Dijkstra 算法

    all the nodes should be carectorized into three groups: (visited, front, unknown) we should pay spec ...

  7. 51nod 1459 迷宫游戏 (最短路径—Dijkstra算法)

    题目链接 中文题,迪杰斯特拉最短路径算法模板题. #include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f ],v ...

  8. 51nod1459(带权值的dijkstra)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1459 题意:中文题诶- 思路:带权值的最短路,这道题数据也没 ...

  9. 求两点之间最短路径-Dijkstra算法

     Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...

随机推荐

  1. python2.0_s12_day9_mysql操作

    mysql的基本语法: 1.数据库操作 show databases; create database 数据库名;如果想允许数据库可以写中文create database 数据库名 charset u ...

  2. 关于MultiByteToWideChar与WideCharToMultiByte代码测试(宽字符与多字节字符的转换)以及字符串的转换代码测试

    #pragma once #include <stdio.h> //getchar() #include <tchar.h> #include <stdlib.h> ...

  3. 元素设置disabled属性后便无法向后台传值

    元素设置disabled属性后便无法向后台传值

  4. 【IOS6.0 自学瞎折腾】(四)Xib可视化编程

    其实在Interface Builder中,要把xib中的控件与代码联系起来用鼠标拖拉连线是非常方便的一件事,有的教程写的非常复杂要先点这后点那的. 一:IBOutlet,IB说明是Interface ...

  5. poj_3185 反转问题

    题目大意 有20个碗排成一排,有些碗口朝上,有些碗口朝下.每次可以反转其中的一个碗,但是在反转该碗时,该碗左右两边的碗也跟着被反转(如果该碗为边界上的碗,则只有一侧的碗被反转).求最少需要反转几次,可 ...

  6. 布局的诡异bug合集+解决方法(更新中)

    1.元素内部子元素的margin的边界线基准点的问题 论如何生硬起名字!!我反正已经被自己总结的题目绕晕了... “演员”介绍: 外层父元素:蓝色边框: 内部子元素:绿色区域: 粉红色区域是元素内部绿 ...

  7. Suricata开源IDS安装与配置

    开源IDS Suricata安装 Linux下的依赖问题的解决 在Debian,Ubuntu或者Linux Mint系列 $ sudo apt-get install wget build-essen ...

  8. 如何获取e.printStackTrace()的内容

    e.printStackTrace()通常是打印在控制台的,但是,有时候程序上线了需要看这个堆栈的内容就不容易了,一来生产环境打印的东西很多或者很少,二来有时候无法直接查看到,这个时候就需要把这些内容 ...

  9. vue监听滚动事件

    vue中监听滚动事件,然后对其进行事件处理,一般有:1. 滚动到顶部吸附: 2. 根据滚动的位置激活对应的tab键(锚链接tab键) 这两种方式的处理都是可通过监听scroll来实现 mounted( ...

  10. VMware Authorization Service 未运行怎么解决

    操作步骤如下: 1.按win+r快捷键,输入services.msc,点击确定: 2.服务列表找到VMware Authorization Service 并双击: 3.修改启动类型为自动,点击应用, ...