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 ...
随机推荐
- Linux-Oracle
1.使用Oracle登录,或者其他用户登录,切换到Oracle账户下: 2.登录后在Oracle主目录后使用vi创建.bashrc文件: 3.在文件中输入如下参数: export ORACLE_SID ...
- 08python之列表的常用方法
列表list是python常用的数据类型,需要掌握以下常用方法: name_list = ['alex','tenglan','65brother'] 这个变量和之前的变量只存一个数字或字符串,这个列 ...
- 原来javascript 自带 encodeURI 和 decodeURI文 方法了
今天百度一下才知道js 自带 encodeURI 和 decodeURI 方法了,之前还找了其他代码来处理(笑哭了.jpg <script type="text/javascript& ...
- 动易CMS漏洞收集
动易SiteWeaver6.8短消息0day跨站漏洞 user用户登陆,默认账号密码 admin/admin888 短消息代码模式下编辑,预览 <img src="../Skin/bl ...
- @ResponseBody将集合数据转换为json格式并返回给客户端
spring-mvc.xml: <beans xmlns:mvc="http://www.springframework.org/schema/mvc" > <m ...
- shell 强大的awk
from here 小用法,使用awk来对文件随机抽取n行 awk 'BEGIN{srand()} {print rand()"\t"$0}' input_file | sort ...
- HTML - 分页效果布局
<p class="jcFY"> 显示 <select name="" id=""> <option valu ...
- LeetCode - Delete Duplicate Emails
Discription:Write a SQL query to delete all duplicate email entries in a table named Person, keeping ...
- bzoj 3307 雨天的尾巴
题目链接:传送门 题目大意:中文题,略 题目思路:网上有题解说是合并线段树的,但是太难蒟蒻不会,只能用树剖求解 如果不是树而是一维数组我们会怎么解? 当然是利用前缀和思想标记 (L) v+1,(R+1 ...
- 【BZOJ3935】Rbtree 树形DP
[BZOJ3935]Rbtree Description 给定一颗 N 个点的树,树上的每个点或者是红色,或者是黑色. 每个单位时间内,你可以任选两个点,交换它们的颜色. 出于某种恶趣味,你希望用最少 ...