题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2433 ,最短路(SPFA或优化过的Dijstra) + 剪枝优化

  这道题关键还是在几个剪枝上面,没有剪枝会TLE。


先说下几个数组的意义:

  a[]存储M条边的信息;vis[i]表示点i是否访问过;path[i][u][v]表示在点i的所有最短路里,边u - v是否属于某条最短路;cnt[u][v]表示边u - v出现的次数;pos[u][i]表示第i条边在邻接表e[u]中的位置;sum[i]表示预处理时顶点i到所有顶点的最短路的和;dist[i]表示顶点i到其他顶点的最短路的距离;e[i]即邻接表,存储与顶点i邻接的点的信息。

算法:

  先预处理一遍,求得每个顶点的最短路,并存在sum[i]中,如果预处理时发现图不连通,则M次询问都输出"INF";

  处理第i条边的时候,如果这条边出现不止一次,即 cnt[u][v] > 1,这时候除掉这条边后不影响结果,输出预处理的结果即可;

  如果不满足上述条件,就开始求n个顶点的最短路情况:求顶点i的最短路的时候,如果边u - v不在顶点i的最短路中,即 path[i][u][v] == 0时,这时候这条边除掉不影响顶点i的最短路的结果,所以仍为sum[i];如果出现去掉这条边图不连通的情况,这次询问输出"INF"。

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = ;
const int maxn = + ;
const int N = + ;
struct Edge {
int v , w;
bool operator < (const Edge &tmp) const {
return w > tmp.w;
}
} a[N];
bool vis[maxn] , path[maxn][maxn][maxn];
int cnt[maxn][maxn] , pos[maxn][N];
int sum[maxn] , dist[maxn];
vector <Edge> e[maxn]; int Dijstra(int s , int n , bool ch) //Dijstra + 优先队列
{ //ch表示是否为预处理,因为在预处理的时候才需要判断path[i][u][v]的情况
memset(vis , , sizeof(vis));
for(int i = ; i <= n ; i++)
dist[i] = INF;
dist[s] = ;
priority_queue <Edge> que;
Edge tmp = {s , };
que.push(tmp);
while(!que.empty()) {
Edge u = que.top();
que.pop();
if(vis[u.v])
continue;
vis[u.v] = ;
for(int i = ; i < e[u.v].size() ; i++) {
int j = e[u.v][i].v;
if(dist[j] > dist[u.v] + e[u.v][i].w) {
dist[j] = dist[u.v] + e[u.v][i].w;
if(!vis[j]) {
if(ch) //这条边在最短路中
path[s][u.v][j] = path[s][j][u.v] = ;
que.push(e[u.v][i]);
}
}
}
}
int ans = ;
for(int i = ; i <= n ; i++) {
if(dist[i] >= INF)
return INF;
ans += dist[i];
}
return ans;
}
int main()
{
int n , m , u , v , i , ans;
while(~scanf("%d %d" , &n , &m))
{
memset(path , , sizeof(path));
memset(cnt , , sizeof(cnt));
for(i = ; i <= n ; i++)
e[i].clear();
for(i = ; i <= m ; i++) {
scanf("%d %d" , &u , &v);
Edge tmp = {v , };
e[u].push_back(tmp);
tmp.v = u;
e[v].push_back(tmp);
pos[u][i] = e[u].size() - ;
pos[v][i] = e[v].size() - ;
cnt[u][v]++;
cnt[v][u]++;
a[i].v = u;
a[i].w = v;
}
bool flag = false;
for(i = , ans = ; i <= n ; i++) {
sum[i] = Dijstra(i , n , );
if(sum[i] == INF) {
flag = true;
break;
}
ans += sum[i];
}
for(i = ; i <= m ; i++) {
u = a[i].v;
v = a[i].w;
if(flag) {
puts("INF");
} else if(cnt[u][v] > ) {
printf("%d\n" , ans);
} else {
int tmp , res;
res = ans;
e[u][pos[u][i]].w = INF; //删掉第i条边
e[v][pos[v][i]].w = INF;
for(int j = ; j <= n ; j++) {
if(path[j][u][v]) {
tmp = Dijstra(j , n , );
if(tmp == INF) {
puts("INF");
break;
}
res += tmp - sum[j];
}
}
if(tmp != INF)
printf("%d\n" , res);
e[u][pos[u][i]].w = ; //还原这条边
e[v][pos[v][i]].w = ;
}
}
}
return ;
}

HDU2433 最短路 + 剪枝优化的更多相关文章

  1. 搜索(剪枝优化):HDU 5113 Black And White

    Description In mathematics, the four color theorem, or the four color map theorem, states that, give ...

  2. hdu 4109 dfs+剪枝优化

    求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己添加的)出发,0到1~n个节点之间的距离为1.mt[i]表示从0点到第i个节点眼下所得的最长路径 #include<iost ...

  3. TensorFlow官方发布剪枝优化工具:参数减少80%,精度几乎不变

    去年TensorFlow官方推出了模型优化工具,最多能将模型尺寸减小4倍,运行速度提高3倍. 最近现又有一款新工具加入模型优化"豪华套餐",这就是基于Keras的剪枝优化工具. 训 ...

  4. 图解Leetcode组合总和系列——回溯(剪枝优化)+动态规划

    Leetcode组合总和系列--回溯(剪枝优化)+动态规划 组合总和 I 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 ...

  5. HDU 6382 odds (暴力 + 剪枝优化)

    odds Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Subm ...

  6. JZYZOJ1442 [noip2013]华容道 bfs 最短路 剪枝

    http://172.20.6.3/Problem_Show.asp?id=1442 想到最短路的简直神了,如果我写我大概只能写一个30分的bfs. 从数据范围可以看出思路是bfs剪枝,但这里的剪枝是 ...

  7. dfs的剪枝优化

    两个剪枝问题 1. 当两点的距离(需要走的步数)大于剩下的时间时 剪去 2.奇偶剪枝问题 如果起点到终点所需走的步数的奇偶性与时间奇偶性不同的时候 剪去 起点到终点步数的奇偶性的判断 首先 明确点的奇 ...

  8. LeetCode37 使用回溯算法实现解数独,详解剪枝优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 数独是一个老少咸宜的益智游戏,一直有很多拥趸.但是有没有想过,数独游戏是怎么创造出来的呢?当然我们可以每一关都人工设置,但是显然这工作量非常 ...

  9. HNU 12847 Dwarf Tower(最短路+队列优化)

    题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12847 解题报告:有n样物品,编号从1到n第i样物品可以通过金 ...

随机推荐

  1. 获取app下载链接

    https://itunes.apple.com/cn/app/id1398635899?mt=8 只需要更改其中的id就可以了

  2. vue入门(一)----组件

    由于工作需要,最近在写一些前端的东西.经过向开发经验丰富的前端工程师的请教之后,得出一个结论----2016年前端被玩坏了,其实对于我来说我并不是太了解这句话的深刻含义,只是觉得是不是因为前端技术突飞 ...

  3. php用百度地图API进行逆地址解析

    <?php /** * 根据地理坐标获取国家.省份.城市,及周边数据类(利用百度Geocoding API实现) * 百度密钥获取方法:http://lbsyun.baidu.com/apico ...

  4. OpenStack基础知识-单元测试工具介绍

    针对以前学的内容的一个简单整理 1.单元测试工具介绍 unittest: 是 Python 的标准库,提供了最基本的单元测试功能,包括 单元测试运行器(简称runner) 和 单元测试框架.项目的单元 ...

  5. Openjudge jubeeeeeat

    jubeeeeeat 题目链接 总时间限制:  1000ms 内存限制:  256000kB 描述 众所周知,LZF很喜欢打一个叫Jubeat的游戏.这是个音乐游戏,游戏界面是4×4的方阵,会根据音乐 ...

  6. 清北刷题冲刺 10-30 a.m

    星空 #include<iostream> #include<cstdio> using namespace std; int n,m; int main(){ freopen ...

  7. 【转载】C#中可使用Unity容器实现属性注入

    简介 Unity :Unity是微软团队开发的一个轻量级,可扩展的依赖注入容器,为松散耦合应用程序提供了很好的解决方案,支持构造器注入,属性注入,方法注入. 控制反转:(Inversion of Co ...

  8. 在谷歌地图上绘制行政区域轮廓【结合高德地图的API】

    实现思路: 1.利用高德地图行政区域API获得坐标列表 2.将坐标列表绘制在谷歌地图上[因为高德地图和国内的谷歌地图都是采用GCJ02坐标系,所有误差很小,可以不进行坐标误差转换] 注意点: 1.用百 ...

  9. mac安装scrapy

    Mac自带python2.7,所以直接安装scrapy.默认安装了Xcode总共分以下几步:1.安装 homebrew.wget2.安装pip3.安装scrapy 安装homebrew在termina ...

  10. centos禁止ping

    1.修改配置文件/etc/sysctl.conf 在这个文件的最后添加一行: net.ipv4.icmp_echo_ignore_all=1 (0 代表允许 1 代表禁止) 2.执行sysctl -p ...