BZOJ 2306 Ctsc2011 幸福路径 倍增Floyd

题目大意:给定一张有向图,每个点有权值,蚂蚁从某个节点出发,初始体力值为1,每走一条边体力值*=p,每经过一个点会获得幸福值为点权*体力值,求最大幸福值

令f[i][j][t]为从点i走到点j花2^t步的最大幸福值

那么有f[i][j][t]=max{f[i][k][t-1]+f[k][j][t-1]*p^(2^t)}

迭代多次即可得到答案的近似值

注意蚂蚁可能卡死在某个点不动,因此初始要将邻接矩阵清为-INF,然后每个点连一条边权为0的自环

此外注意下卡死时最后经过的那个点的权值会不会被统计 这里可能会挂

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 110
using namespace std;
int n,m,st;
double p,ans,a[M],f[M][M],g[M][M];
int main()
{
	int i,j,k,T,x,y;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		scanf("%lf",&a[i]);
	cin>>st>>p;
	memset(f,0xc2,sizeof f);
	for(i=1;i<=n;i++)
		f[i][i]=0;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		f[x][y]=a[y];
	}
	double temp=p;
	for(T=0;T<=70;T++,temp*=temp)
	{
		memset(g,0xc2,sizeof g);
		for(k=1;k<=n;k++)
			for(i=1;i<=n;i++)
				for(j=1;j<=n;j++)
					g[i][j]=max(g[i][j],f[i][k]+f[k][j]*temp);
		memcpy(f,g,sizeof f);
	}
	for(i=1;i<=n;i++)
		ans=max(ans,f[st][i]);
	printf("%.1lf\n",ans*p+a[st]);
	return 0;
}
时间: 2024-08-05 14:31:15

BZOJ 2306 Ctsc2011 幸福路径 倍增Floyd的相关文章

bzoj2306 幸福路径 倍增 Floyd

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2306 题意:一张有向图,每个点有一个权值$w(x)$,给出路径起点求出最大$f(x)=sigma(w(x)*p)$,其中,$p$初始值为$1$,每走一步这个值都会乘上另一个给出的常量. 由于这个题精度要求极低(只有$1e-1$),所以我们直接迭代求值即可. 但是如果我们这么一步一步搞肯定会$T$……这时候我们就需要用一些黑科技:倍增.我们每次倍增前进,前进的时候在每一层做一次$Floyd$,

bzoj2306: [Ctsc2011]幸福路径(倍增+Floyed 逼近答案)

www.cnblogs.com/shaokele/ bzoj2306: [Ctsc2011]幸福路径 Time Limit: 10 Sec Memory Limit: 256 MB Description 有向图 G有n个顶点 1, 2, -, n,点i 的权值为 w(i).现在有一只蚂蚁,从给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条边,它的体力都会下降为原来的 ρ 倍,其中ρ 是一个给定的小于1的正常数.而蚂蚁爬到某个顶点时的幸福度,是它当时的体力与该点权值

BZOJ2306 [Ctsc2011]幸福路径

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目链接:BZOJ2306 正解:倍增+floyd 解题报告: 这道题很有意思啊... 显然不能直接算贡献,考虑概率衰减的很快,我们可以做到一定的次数就视为得到了最优解,精度够了就行. 而这个$floyd$的过程可以用倍增加速,考虑用$f[t][i][j]

BZOJ 2085 [Poi2010]Hamsters Hash+倍增floyd

题意:链接 方法: Hash+倍增floyd 解析: 首先这个BZ的无脑翻译我真是受不了. 加俩条件 所有串的长度总和不超过100000,并且对于任意不同子串A,B,A不包含于B,B不包含于A. 然后可以做题了. 首先,我们可以暴力hash搞出来如果i串后面接j串则需要增加多少长度. 这个n非常的小所以直接开数组记录. 然后就是倍增floyd了. 至于前半部分为什么是复杂度可以接受的. 参见PoPoQQQ的证明,总之我们要求的 ∑∑(min(leni,lenj))的函数的最大化时,复杂度是O(l

CTSC2011 幸福路径

给定?张有向图,每个点有个权值,蚂蚁从某个点开始,初始体?为1,每经过?条边,体?会变为原来的p(0<p<1)倍,每爬到?个点,获得的幸福度为该点的权值乘上体?.求蚂蚁幸福度的最?值,保留?位?数. $n \leq 100,点权 \leq 100$ sol: 正解是自动机的泵引理,一看就不可做,考虑暴力碾标算 由于点权不超过 100,体力很小的时候点权的贡献也很小,保留一位小数就会把很小的贡献舍去 做一个 dp 设 $f_{(i,j,k)}$ 表示走了 $i$ 步,从 $j$ 走到 $k$ 的

BZOJ 2306 幸福路径(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2306 题意:给出一个有向图,点有权值 a.初始时在点S.一个人在初始点能量为K=1,每走到下一个点能量值乘以p(p<1),到达一个点u 幸福度为 a[u]*K.求最大的幸福度. 思路:最后必然是走了一条链,或者是一个环(一直绕),或者是一条链加一个环.设f[i][j][k]表示从点j走了i步到达节点k的最大幸福度.那么f[i][j][j]就表示在绕环.那么在这个环上一直绕下去的期望为:

BZOJ 2165 大楼 倍增Floyd

题目大意:给定一张图,求从1开始到达m的权值至少需要遍历多少条边 n<=100,果断倍增Floyd f[temp][i][j]表示经过2^temp条边从i走到j的最大权值 更新时f[temp[i][j]=max{f[temp-1][i][k]+f[temp-1][k][j]} 然后用矩阵g[i][j]记录当前走的权值,初始主对角线为0,其余为-∞ 从大到小枚举temp,利用f[temp]和g得到矩阵h 如果h中1到某个点的权值超过了m就跳出 否则将当前temp计入ans 然后将g数组更新为h 最

BZOJ 1706 usaco2007 Nov relays 奶牛接力跑 倍增Floyd

题目大意:给定一张无向图,求从s出发恰好经过n条边到达e的最短路 倍增Floyd--为何大家都管这个叫做矩阵乘法- - 算了为何要纠结这种事- - 令f[p][i][j]表示走2^p步从i到达j的最短路 有f[p][i][j]=min{f[p-1][i][k]+f[p-1][k][j]} 将n进行二进制拆分 用矩阵g记录答案矩阵 对于每一位p 用f[p]和g两个矩阵搞出h 再将h的值赋给g 切忌直接用f[p]更新g 这样可能导致g的上一次的值被继承到下一次里 这样相当于这一步没跑 100条边,因

[BZOJ] 幸福路径

bzoj 2306 最短路水题,多次迭代就可以求得答案. 我在这里迭代了100下,应该很安全了orz #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int N = 110; int n,m,s; double ans,g[N][N],a[N],f[N][N],p