uva1416 dijkstra
大白书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的更多相关文章
- Dijkstra 单源最短路径算法
Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...
- 最短路径算法-Dijkstra
Dijkstra是解决单源最短路径的一般方法,属于一种贪婪算法. 所谓单源最短路径是指在一个赋权有向图中,从某一点出发,到另一点的最短路径. 以python代码为例,实现Dijkstra算法 1.数据 ...
- [板子]最小费用最大流(Dijkstra增广)
最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...
- POJ 2253 Frogger(Dijkstra)
传送门 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 39453 Accepted: 12691 Des ...
- POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)
传送门 Til the Cows Come Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 46727 Acce ...
- Dijkstra 算法
all the nodes should be carectorized into three groups: (visited, front, unknown) we should pay spec ...
- 51nod 1459 迷宫游戏 (最短路径—Dijkstra算法)
题目链接 中文题,迪杰斯特拉最短路径算法模板题. #include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f ],v ...
- 51nod1459(带权值的dijkstra)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1459 题意:中文题诶- 思路:带权值的最短路,这道题数据也没 ...
- 求两点之间最短路径-Dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...
随机推荐
- mysql 中实现行变列
前言: mysql行列变化,最难的就是将多个列变成多行,使用的比较多的是统计学中行变列,列变行,没有找到现成的函数或者语句,所以自己写了存储过程,使用动态sql来实现,应用业务场景,用户每个月都有使用 ...
- 【RF库Collections测试】Dictionary Should Contain Sub Dictionary
Name:Dictionary Should Contain Sub DictionarySource:Collections <test library>Arguments:[ dict ...
- Does the parameter type of the setter match the return type of the getter?
JDK 1.8, dubbo-admin版本是2.5.4-SNAPSHOT,tomcat8.5启动,报错: ERROR context.ContextLoader - Context initiali ...
- cut的用法【转】
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的.一般来说,选取信息通常是针对“行”来进行分析的,并不是整篇信息分析的. (1)其语法格式为:cut [-bn] [file] 或 cut ...
- mysql的if null 的用法
<!-- 查询 分页查询 --> <select id="queryByPageList" resultMap="weixinActivityResul ...
- MUI Hbuilder设置模拟器运行APP项目
1 安装hbuilder和夜神模拟器 2 hbuilder 新建app项目 3 hbuilder:运行-> 设置web服务器->Hbuilder 第三方安卓模拟器端口:62001 4 运 ...
- LeetCode - Department Highest Salary
题目大概的意思是选出每个Department里工资最高的人的信息并组成相应的表信息 有几个值得注意的地方:1)使用group by语句时,前面的select语句后面的内容只能有两种情况一种是group ...
- 使用commons-email解析 eml文件
在对eml文件进行索引的时候需要先对其进行解析,提取出其中的收件人.发件人.文件内容和附件等信息 下边是解析eml文件的一个demo(在运行之前需要先导入mail.jar 和commons-email ...
- 【BZOJ3678】wangxz与OJ Splay
[BZOJ3678]wangxz与OJ Description 某天,wangxz神犇来到了一个信息学在线评测系统(Online Judge).由于他是一位哲♂学的神犇,所以他不打算做题.他发现这些题 ...
- 【BZOJ2595】[Wc2008]游览计划 斯坦纳树
[BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...