大白书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. ionic跳转(一)

    在ionic中可以用两个办法写中转链接(写模版地址或路由地址) 1)a 标签的 href <a class="button button-icon icon ion-android-h ...

  2. Redis(二)-- 发布订阅、事务、安全、持久化

    一.Redis发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 打开两个窗口:session1 和 session2 在sess ...

  3. Linux同步网络时间

    1.date '+%Y%M%D' 按照格式显示当前日期,结果如下: [root@LAMP ~]# date "+%Y-%m-%d %H:%M:%S" -- :: 2.date -s ...

  4. 【算法】深度优先搜索(DFS)III

    1. DFS生成排列 众所周知,1,2…n的排列一共有n!个,因此生成全排列至少需要n!的时间复杂度.如果用循环来生成排列,当n稍大时,内外循环会非常之多.可以用DFS模拟解决,生成0 … n-1的排 ...

  5. LeetCode——Min Stack

    Description: Design a stack that supports push, pop, top, and retrieving the minimum element in cons ...

  6. 用ajax实现用户名的检测(JavaScript方法)

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  7. 部署软件RDMA的步骤

    date:  2018-08-28   19:46:56 参考原文原文:http://corasql.blog.51cto.com/5908329/1930455                    ...

  8. svn-maven-tomcat自动发布脚本

    #!/bin/sh #svn-maven-tomcat自动发布脚本 #变量设置 svnpath=svn://10.60.10.120/研发部/xx-maven svnusername=xxx svnp ...

  9. session.cookie.lifetime和session.gc.maxlifetime的关系

    session.cookie.lifetime session.cookie.lifetime 默认是0,即浏览器关闭,session失效:修改这个值的作用是修改sessionid以cookie的形式 ...

  10. 修改字段字符集 mysql 修改 锁表 show processlist; 查看进程 Waiting for table metadata lock

    ALTER TABLE `question` MODIFY COLUMN `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unico ...