蓝书3.3 SPFA算法的优化
T1 最小圈 bzoj 1486
题目大意:
一个环的权值平均值为定义为一个这个环上所有边的权值和除以边数
求最小的环的权值平均值
思路:
二分一个值 把所有边减去这个值
判断是否有负环
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #define inf 1061109567
- #define ll long long
- #define MAXN 6010
- #define eps 1e-9
- using namespace std;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
- while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- int n,m,vis[MAXN],fa[MAXN],q[MAXN],f;
- double l,r,mid,ans,dis[MAXN],val[MAXN<<],v[MAXN<<];
- int to[MAXN<<],nxt[MAXN<<],fst[MAXN],cnt;
- void add(int u,int v,double w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
- void spfa(int x)
- {
- vis[x]=;
- for(int i=fst[x];i;i=nxt[i])
- if(dis[x]+v[i]<dis[to[i]])
- if(vis[to[i]]){f=;return;}
- else {dis[to[i]]=v[i]+dis[x];spfa(to[i]);}
- vis[x]=;
- }
- int check(double x)
- {
- for(int i=;i<=cnt;i++) v[i]=val[i]-x;
- for(int i=;i<=n;i++) dis[i]=0.0;
- memset(vis,,sizeof(vis));f=;
- for(int i=;i<=n;i++)
- {spfa(i);if(f) return ;}
- return ;
- }
- int main()
- {
- n=read(),m=read();int a,b;double c;
- while(m--) {a=read(),b=read();scanf("%lf",&c);add(a,b,c);}
- l=-1e7,r=1e7;
- while(r-l>=eps)
- {
- mid=(l+r)/2.0;
- if(check(mid)) ans=mid,r=mid-eps;
- else l=mid+eps;
- }
- printf("%.8lf",ans);
- }
T2 虫洞 bzoj 1715
题目大意:
一个无向图中有一些虫洞 虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻
求是否可以借助这些虫洞来回到出发时刻之前
思路:
把有向图的边权改为负的 直接用dfs的spfa判负环即可
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #define inf 1061109567
- #define ll long long
- #define MAXN 3010
- #define eps 1e-5
- using namespace std;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
- while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- int n,m1,m2,dis[MAXN],vis[MAXN],fa[MAXN],q[MAXN],f;
- int to[MAXN<<],nxt[MAXN<<],val[MAXN<<],fst[MAXN],cnt;
- void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
- void spfa(int x)
- {
- vis[x]=;
- for(int i=fst[x];i;i=nxt[i])
- if(dis[x]+val[i]<dis[to[i]])
- if(vis[to[i]]){f=;return;}
- else {dis[to[i]]=val[i]+dis[x];spfa(to[i]);}
- vis[x]=;
- }
- int main()
- {
- int T=read();
- while(T--)
- {
- n=read(),m1=read(),m2=read(),f=;int a,b,c;
- memset(dis,,sizeof(dis));memset(vis,,sizeof(vis));
- memset(fst,,sizeof(fst));cnt=;
- while(m1--) {a=read(),b=read(),c=read();add(a,b,c);add(b,a,c);}
- while(m2--) {a=read(),b=read(),c=read();add(a,b,-c);}
- for(int i=;i<=n;i++)
- {spfa(i);if(f) {puts("YES");goto ed;}}
- puts("NO");
- ed:;
- }
- }
T3 Easy sssp vijos 1053
题目大意:
判断这个有向图中是否存在负权回路
如果存在负权回路, 只输出一行-1 如果不存在负权回路, 再求出一个点S到每个点的最短路的长度
思路:
不知道我的dfs spfa 为什么T了
于是选择bfs 如果一个点进队n次 则有负环
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #define inf 2147483647
- #define ll long long
- #define MAXN 50100
- #define eps 1e-9
- using namespace std;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
- while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- int n,m,vis[MAXN],fa[MAXN],q[MAXN<<],l,r,f,st,inq[MAXN],num[MAXN];
- int to[MAXN<<],nxt[MAXN<<],fst[MAXN],dis[MAXN],val[MAXN<<],cnt;
- void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
- int spfa(int s)
- {
- memset(inq,,sizeof(inq));
- memset(num,,sizeof(num));
- for(int i=;i<=n;i++) dis[i]=inf;
- dis[s]=,q[l=r=]=s;int x;
- while(l<=r)
- {
- x=q[l++],inq[x]=;
- if(dis[s]<) return ;
- for(int i=fst[x];i;i=nxt[i])
- if(!vis[to[i]]&&dis[to[i]]>dis[x]+val[i])
- {
- dis[to[i]]=dis[x]+val[i];
- if(!inq[to[i]]) q[++r]=to[i],inq[to[i]]=;
- if(++num[to[i]]>n) return ;
- }
- }
- for(int i=;i<=n;i++) vis[i]=vis[i]||num[i];
- return ;
- }
- int check()
- {
- for(int i=;i<=n;i++)
- if(!vis[i]) if(!spfa(i)) return ;
- return ;
- }
- int main()
- {
- n=read(),m=read(),st=read();int a,b,c;
- while(m--) {a=read(),b=read(),c=read();add(a,b,c);}
- if(check()) {puts("-1");return ;}
- memset(vis,,sizeof(vis));spfa(st);
- for(int i=;i<=n;i++)
- if(dis[i]==inf) puts("NoPath");
- else printf("%d\n",dis[i]);
- }
蓝书3.3 SPFA算法的优化的更多相关文章
- 关于SPFA算法的优化方式
关于SPFA算法的优化方式 这篇随笔讲解信息学奥林匹克竞赛中图论部分的求最短路算法SPFA的两种优化方式.学习这两种优化算法需要有SPFA朴素算法的学习经验.在本随笔中SPFA朴素算法的相关知识将不予 ...
- 《SPFA算法的优化及应用》——姜碧野(学习笔记)
一.核心性质:三角不等式.最短路满足d[v]<=d[u]+w(u,v) 二.SPFA两种实现: 常见的是基于bfs的,这是直接对bellman-ford用队列维护.根据最短路的长度最长为(n-1 ...
- 并不对劲的图论专题(三):SPFA算法的优化
1.bzoj1489-> 这是个新套路. 我们希望找到最小的x,那么可以二分x,然后判断是否存在圈的边权的平均值小于等于x. 设圈的边权依次为w1,w2,w3,…,wk,平均值为p, 则有p= ...
- 蓝书2.2 KMP算法
T1 Radio Transmission bzoj 1355 题目大意: 一个字符串,它是由某个字符串不断自我连接形成的 但是这个字符串是不确定的,现在只想知道它的最短长度是多少 思路: kmp 输 ...
- 队列优化dijsktra(SPFA)的玄学优化
转载:大佬博客 最近想到了许多优化spfa的方法,这里想写个日报与大家探讨下 前置知识:spfa(不带任何优化) 由于使用较多 STLSTL ,本文中所有代码的评测均开启 O_2O2 优化 对一些数 ...
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...
- SPFA求最短路——Bellman-Ford算法的优化
SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环.SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE), ...
- SPFA算法 - Bellman-ford算法的进一步优化
2017-07-27 22:18:11 writer:pprp SPFA算法实质与Bellman-Ford算法的实质一样,每次都要去更新最短路径的估计值. 优化:只有那些在前一遍松弛中改变了距离点的 ...
- luogu P3371 & P4779 单源最短路径spfa & 最大堆优化Dijkstra算法
P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出 ...
随机推荐
- 集训第六周 数学概念与方法 数论 筛素数 H题
Description 小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识. 问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为“ ...
- Java语言编写TPL语言词法分析器
程序实现原理: 将TXT文本中的数据读出,并按照其类别的不同,将关键字.数字以及运算符识别出来. 一.词法分析实验步骤 1. 熟悉TPL语言 2. 编写TPL语言程序,至少3个,一个简单,一个复杂的( ...
- BNUOJ 5997 Fibonacci again and again
Fibonacci again and again Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HD ...
- [luoguP1058] 立体图(超级大模拟(¬︿̫̿¬☆))
传送门 看到题后整个人成了mengbier 但是仔细分析一下就很简单了,先确定好输出的图的长和宽. 然后从输入的矩形的左上角的最下面的开始填充,顺序是从下到上,从左到右,从后往前. 填充的时候直接覆盖 ...
- SQLAlchemy(2):多表操作 & 连接方式及原生SQL
一对多:ForeignKey multitb_models.py import datetime from sqlalchemy import create_engine # 引入 创建引擎 from ...
- MVC Ajax.BeginForm重复提交解决方法
mvc使用MVC Ajax.BeginForm提交的时候有重复提交结果的时候检查相关js文件引用情况, 其中mvc4注意 1 2 3 4 @Scripts.Render("~/bundles ...
- UVA 437_The Tower of Babylon
题意: 一堆石头,给定长宽高,每种石头均可以使用无数次,问这堆石头可以叠放的最高高度,要求下面的石头的长和宽分别严格大于上面石头的长和宽. 分析: 采用DAG最长路算法,由于长宽较大,不能直接用于表示 ...
- [bzoj2150]部落战争_二分图最小路径覆盖
部落战争 bzoj-2150 题目大意:题目链接. 注释:略. 想法: 显然是最小路径覆盖,我们知道:二分图最小路径覆盖等于节点总数-最大匹配. 所以我们用匈牙利或者dinic跑出最大匹配,然后用总结 ...
- 51Nod——T 1686 第K大区间
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 ...
- 一步步搭建java信息管理系统00 - 前言
开发前,先上效果图吧 信息管理系统,个人认为,以下几个因素是不可缺少的 多tab 因菜单比较多,右侧的树形一定要考虑,如果菜单还是多,那么顶部就要考虑起来了 以后想到什么,再添加吧. 看到easyui ...