hdu 1595 find the longest of the shortest (dijkstra + spfa)
来源:互联网 发布:java 什么是包 编辑:程序博客网 时间:2024/05/22 13:38
find the longest of the shortest
题目大意:现有一个无向图,其中某一条边不存在(要删除),求所有情况中最短路里的最大值。
题目分析:
思路一:枚举m条边,一一删除进行spfa求出最短路,然后比较出最大值。(超时)
思路二:先利用dijkstra求出最短路,再在最短路里枚举个边,一一删除进行spfa求出最短路,然后比较最大值。(AC)
思路分析:之所以能在最短路里删边求最小值,避免了一一枚举m条边,是因为删边后最短路要保持其值小,如果删除最短路意外的边,所有最小值都等于最短路的值,就不存在最大值了,所以利用原来最短路的基础上删边是优化的正确选择。
步骤: 1)存图 vector
2)找最短路 dijkstra
3)路径还原 (前驱)
4)在最短路中一一删边,每次求出最短路,比较出最大值(spfa)
贴AC代码:
#include <stdio.h> //定义输入/输出函数#include <limits.h> //定义各种数据类型最值常量#include <math.h> //定义数学函数#include <stdlib.h> //定义杂项函数及内存分配函数#include <string.h> //字符串处理#include <algorithm>//算法#include <queue>//队列#include <stack>//栈#include <vector>using namespace std;int n, m;int vis[1005];int road[1005]; //记录路径int a, b, t, couts, _a, _b, k;unsigned int ans, maxs;struct qq{ int to, cost;};qq input;vector <qq> v[1005]; //存图struct node{ int cost, pre;};node low[1005]; //dijkstra用struct pp{ int loc, cost; friend bool operator < (pp a, pp b) { return a.cost > b.cost; }}; //spfa优先队列用void dijkstra() //求最短路径并还原路径 wa在此处3次{ for (int i = 1; i <= n; i++){ low[i].cost = 10000005; low[i].pre = 0; } memset(vis, 0, sizeof(vis)); low[1].cost = low[1].pre = 0; vis[1] = 1; for (int i = 0; i < v[1].size(); i++){ low[v[1][i].to].cost = v[1][i].cost; low[v[1][i].to].pre = 1; } for (int j = 1; j < n; j++){ unsigned int mins = -1; int loc = 1; for (int i = 1; i <= n; i++){ if (low[i].cost && low[i].cost < mins && vis[i] == 0){ mins = low[i].cost; loc = i; } } //找到最小值位置 vis[loc] = 1; for (int i = 0; i < v[loc].size(); i++){ if (vis[v[loc][i].to] == 1) continue; // 如果满足更新后的距离小于原来的值,则可以更新,并更新前驱 if (low[v[loc][i].to].cost > low[loc].cost + v[loc][i].cost){ low[v[loc][i].to].cost = low[loc].cost + v[loc][i].cost; low[v[loc][i].to].pre = loc; } } } //路径还原 k = n; couts = 0; road[couts++] = k; while(k != 0){ road[couts++] = low[k].pre; k = low[k].pre; }}void spfa() //求最短路的spfa 被题目绕进去了一开始求了最大值,wa了一次{ priority_queue <pp> q; while (!q.empty()) q.pop(); memset(vis, 0, sizeof(vis)); pp start; start.loc = 1; start.cost = 0; q.push(start); while (!q.empty()){ pp news, tmp; tmp = q.top(); q.pop(); vis[tmp.loc] += 1; if (tmp.loc == n){ if (ans > tmp.cost) ans = tmp.cost; break; } //要求出每次删边的最短路! for (int i = 0; i < v[tmp.loc].size(); i++){ news = tmp; if (vis[v[tmp.loc][i].to] == 1) continue; if (vis[tmp.loc] > 1) continue; //删边 if (tmp.loc == _a && v[tmp.loc][i].to == _b) continue; if (v[tmp.loc][i].to == _a && tmp.loc == _b) continue; news.loc = v[tmp.loc][i].to; news.cost += v[tmp.loc][i].cost; //printf("%d -> %d , cost %d\n", tmp.loc, news.loc, news.cost); q.push(news); } }}int main(){ while (scanf("%d", &n) != EOF && n){ scanf("%d", &m); for (int i = 0; i < 1005; i++) v[i].clear(); for (int i = 0; i < m; i++){ scanf("%d%d%d", &a, &b, &t); input.to = b; input.cost = t; v[a].push_back(input); input.to = a; v[b].push_back(input); } dijkstra(); maxs = 0; for (int i = 0; i < couts - 1; i++){ //printf(" -> %d ", road[i]); _a = road[i]; _b = road[i+1]; ans = -1; spfa(); if (maxs < ans) maxs = ans; //在每次求出的最短路中找出最大值 } printf("%d\n", maxs); }}
0 0
- hdu 1595 find the longest of the shortest (dijkstra + spfa)
- hdu 1595 find the longest of the shortest ( spfa + 枚举 )
- find the longest of the shortest (hdu 1595 SPFA+枚举)
- HDU 1595find the longest of the shortest(spfa)
- hdu 1595 find the longest of the shortest (spfa)
- HDU 1595 find the longest of the shortest(Dijkstra)
- HDU 1595 find the longest of the shortest (Dijkstra)
- hdu 1595 find the longest of the shortest (dijkstra)
- hdu 1595 find the longest of the shortest(dijkstra)
- HDU 1595 find the longest of the shortest (Dijkstra算法)
- hdu 1595 find the longest of the shortest (Dijkstra)
- hdu 1595 find the longest of the shortest(最短路spfa)
- HDU - 1595 find the longest of the shortest(最短路Dijkstra+枚举删边)
- hdu 1595 find the longest of the shortest (Dijkstra+路径处理)
- hdu 1595 find the longest of the shortest 最短路dijkstra+枚举
- find the longest of the shortest HDU
- find the longest of the shortest HDU
- HDU 1595 find the longest of the shortest
- Linux基础: 解密module_init幕后的故事
- backlight 子系统
- uboot中nand flash控制器参数TACLS、TWRPH0和TWRPH1的确定(基于K9F2G08U0B)
- 深度分析NandFlash—控制器参数TACLS、TWRPH0和TWRPH1的确定(以TQ2440开发板上的K9F2G08U0A为例)
- MTD子系统归纳总结
- hdu 1595 find the longest of the shortest (dijkstra + spfa)
- 基于MTD的NAND驱动开发
- Linux内核入门—— __attribute__ 机制
- kzalloc详解
- Makefile
- linux字符cdev和Inode的关系
- HAL层开发框架介绍
- class.c重要函数浅析
- va_start va_end 的使用和原理