本题的关键在于:

  1. 建图
  2. 01分数规划
  3. 本题的数据过大,如果直接spfa判断会TLE,因此我们使用经验优化,就是如果所有的点入队的次数过多,比如大于100000,那么我们直接认为它是存在正环的。(免去TLE,但是这个不一定对)
  • 建图

做一个对偶

主要是除了两端的两个字母有用以外,字符串中间的其他所有的字符都没有用,因此我们可以直接这样建图:直接hash两端的两个字母作为结点,边的权值为该字符串的个数。这样建的图结点和边的个数为1e7,没有超限。


如果我们直接像下面这样暴力建图,数据会达到1e10,不可取。

  • 题目要求先判断是否有解:

如果m = 0的时候无解,那么m>0时更无解

  • 01规划:

我们要求的是平均长度,也就是每一条字符串的长度之和除以总的字符串个数,换成数学公式即为下式(个数对于每一个字符串来说都是1):
∑wi∑1\frac{\sum w_i}{\sum 1}∑1∑wi​​
要求这个值最大,满足单调性,很明显是一个01分数规划问题,自然使用二分答案。我们设答案为mid
那么如果当前答案不够需要更大,上式即为∑wi∑1>mid\frac{\sum w_i}{\sum 1}>mid∑1∑wi​​>mid
化简以后:∑wi>mid∗∑1\sum w_i>mid * \sum 1∑wi​>mid∗∑1
∑wi>∑mid\sum w_i>\sum mid ∑wi​>∑mid
∑wi−∑mid>0\sum w_i - \sum mid > 0∑wi​−∑mid>0

那么也就是说对于每一个边,给它赋权值wi−midw_i - midwi​−mid,如果存在正环,也就意味着有一个环的权值和大于0,也就是∑wi−∑mid>0\sum w_i - \sum mid > 0∑wi​−∑mid>0,就意味着mid需要更大。

这里可以直接用权值建图,然后直接跑spfa,把不同的mid放到更新最短路时减去,因为每次只是-mid,跟其他的没有关系,就不用像上一道题那样每次重新建图了。

eps=1e-4,应该是double类型!

使用经验优化或者将队列换成栈都可以AC

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>using namespace std;const int N = 1000, M = 500007, INF = 0x3f3f3f3f;
const double eps = 1e-4;int ver[M],nex[M],edge[M],head[N],tot = 1;
int n;//这里的n是字符的个数
int m;
int q[N],cnt[N],vis[N];
double dist[N];void add(int x,int y,int z){ver[++tot] = y;edge[tot] = z;nex[tot]  =head[x];head[x] = tot;
}bool check(double mid){memset(cnt,0,sizeof cnt);memset(vis,0,sizeof vis);int hh = 0,tt = 0;for(int i = 0;i < 676;++i){q[tt ++ ] = i;vis[i] = true;}int counts = 0;//经验优化while(hh != tt){int x = q[hh ++ ];if(hh == N)hh = 0;vis[x] = false;for(int i = head[x];~i;i = nex[i]){int y = ver[i],z = edge[i];if(dist[y] < dist[x] + z - mid){dist[y] = dist[x] + z - mid;cnt[y] = cnt[x] + 1;counts ++ ;if(counts > 10000)return true;if(cnt[y] >= N)return true;if(!vis[y]){vis[y] = true;q[tt ++ ] = y;if(tt == N)tt = 0;}}}}return false;
}int main(){while(scanf("%d",&n) && n){memset(head,-1,sizeof head);tot = 1;for(int i = 1;i <= n;++i){char s[1010];scanf("%s",s);int len = strlen(s);if(len < 2)continue;int a = (s[0] - 'a' )* 26 + s[1] - 'a';int b = (s[len - 2] - 'a') * 26 + s[len - 1] - 'a';add(a,b,len);}if(!check(0))puts("No solution");else {double l = 0,r = 1000;while(r - l > eps){double mid = (l + r) / 2;if(check(mid))l = mid;else r = mid;}printf("%lf\n",r);}}return 0;
}

解题报告:AcWing 1165. 单词环(01分数规划、hash、经验优化)相关推荐

  1. 算法提高课-图论-负环-AcWing 1165. 单词环:spfa判正环、二分、01分数规划

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 如何建图? 这样建图.以样例举例.起点是前两个字母,终点是末尾两个字母,边权是字符串的长度. 我们求的是什么呢? 题目要求Σ边权Σ1 ...

  2. 【图论专题】负环与01分数规划

    整理的算法模板合集: ACM模板 题目列表: 题目 算法 AcWing 904. 虫洞 spfa判负环 AcWing 361. 观光奶牛 最优比率环.01分数规划 AcWing 1165. 单词环 0 ...

  3. 算法提高课-图论-负环-AcWing 361. 观光奶牛:spfa判正环、负环、01分数规划、二分

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 题目要求ΣfiΣgi\frac{\Sigma{f_i}}{\Sigma{g_i}}Σgi​Σfi​​的最大值,这种问题称为01分数规 ...

  4. P1768-天路【负环,SPFA,01分数规划,二分答案】

    正题 题目链接:https://www.luogu.org/problemnew/show/P1768 题目大意 求一条回路使得路上∑vi∑pi\frac{\sum v_i}{\sum p_i}∑pi ...

  5. 模板 - 判断负环(超时高效优化技巧)、01分数规划

    整理的算法模板合集: ACM模板 判断负环 判正环求最长路,判负环求最短路 int n; // 总点数 int h[N], w[N], e[N], ne[N], idx; // 邻接表存储所有边 in ...

  6. POJ-3621 Sightseeing Cows 最优比率环、01分数规划

    题目链接:http://poj.org/problem?id=3621 这题是01分数规划问题,详细资料点这里.有了01分数规划的基础后,这个题目就很简单了.构建函数f(mid)=Σ(w[i]-mid ...

  7. bzoj 1690: [Usaco2007 Dec]奶牛的旅行(01分数规划--最优比率环)

    01分数规划问题: 给你n个物品,a[i]表示第i个物品的收益,b[i]表示代价,x[i]表示选或不选,求一个最佳方案使得下式取值最大 通用解: 当然是从式子上考虑,定义函数F[cnt]如下: 其中c ...

  8. 转载二分 01 分数规划即最大化平均值的证明0/1分数规划、最优比率生成树、最优比率环

    首页 新随笔 联系 管理 订阅 随笔- 20  文章- 0  评论- 9 [Algorithm]01分数规划--Update:2012年7月27日 [关键字] 0/1分数规划.最优比率生成树.最优比率 ...

  9. 点分治问题 ----------- luoguP2942 [WC2010]重建计划 [点分治 + bfs + 单调队列 + 预处理建树 + 二分 + 01分数规划]

    题目链接 解题思路: 1.对于这个Avgvalue=∑e∈sv(e)∣s∣Avgvalue = \frac{\sum_{e\in s}v(e)}{|s|}Avgvalue=∣s∣∑e∈s​v(e)​ ...

最新文章

  1. 土地档案管理系统需求分析
  2. 当前国内有哪些公司是做OKR管理软件做的比较好的?
  3. 哈夫曼树哈夫曼编码(已知A,B,C,D,E,F,G的概率分别为:17,25,50,67,40,60,30.画出其哈夫曼树和每个字符对应的哈夫曼编码)
  4. InnoDB,5项实践
  5. 基于SSM实现旅游酒店预定管理系统平台
  6. 实验四十一、×××(IPSec)的配置
  7. webpack4.x安装的一些坑
  8. POJ - 2480 Longge's problem(欧拉函数+唯一分解定理)
  9. 09.multi-get api操作
  10. TexBox.AutoCompleteSource
  11. python对json的相关操作
  12. [转载] 2020最新Java面试题,常见面试题及答案汇总
  13. vb mysql 表格显示,在VB中编辑数据库和电子表格
  14. 浅析HandlerThread
  15. 祝贺在龙芯平台上编译jogamp(gluegen/jogl)2.3.2通过,并运行成功
  16. 什么是html文件?html格式如何打开?(图文讲解)
  17. Python编程基础及应用
  18. 比夏洛克还厉害:人工智能开始协助警方破案
  19. 萨姆·阿尔特曼:如何获得成功(How To Be Successful)译文
  20. C#windows图书信息管理系统

热门文章

  1. 卧槽!阿里《算法进阶指南》火了,完整版 开放下载!
  2. 新一代企业内部故障报修软件功能实现
  3. web自适应尺寸方法
  4. Apple Watch学习之路 生命周期研究
  5. 周鸿祎重做路由器,到底在做什么?
  6. Python 1 数据类型的操作
  7. 分布式团队面临的五大问题及解决办法
  8. App Store 申请审核加速
  9. LeetCode:Remove Nth Node From End of List
  10. nginx-0.1.0文件分析3:ngx_send.c