P3597-[POI2015]WYC【矩阵乘法,倍增】

前言

P3597-[POI2015]WYC【矩阵乘法,倍增】_第1张图片


正题

题目链接:https://www.luogu.org/problemnew/show/P3597


题目大意

问第 k k k长的路径长度(非简单路径)


解题思路

先考虑 k k k比较小时的情况,我们可以求出长度为 1 1 1的路径,长度为 2 2 2的路径,然后以此类推找到第一个与前面的和到 k k k就可以得出答案。

但是这样并不能通过本题,我们考虑 倍 增 + 矩 阵 乘 法 倍增+矩阵乘法 +

首先因为边权只有 1 , 2 , 3 1,2,3 1,2,3所以我们可以拆点, ( k − 1 ) ∗ x (k-1)*x (k1)x表示 x x x出发的边上已经走了 k k k步。

首先 ( k ∗ i ) − > ( k ∗ i + k ) (k*i)->(k*i+k) (ki)>(ki+k),若一条边 x − w > y x-_w>y xw>y那么 ( w − 1 ) ∗ x − > y (w-1)*x->y (w1)x>y就可以了,这样 ( i , j ) (i,j) (i,j)就是 i i i j j j的路径条数

用矩阵 G k G_k Gk中的 ( i , j ) (i,j) (i,j)表示 i i i j j j的路径长度 ≤ 2 k \leq2^k 2k的有多少条,且 ( i , 0 ) (i,0) (i,0)表示以 i i i为终点的长度 ≤ 2 k \leq2^k 2k有多少条。

那么有 G k = G k − 1 ∗ G k − 1 G_k=G_{k-1}*G_{k-1} Gk=Gk1Gk1

然后若答案为 a n s ans ans,那么有
∑ 2 x i = a n s \sum2^{x_{i}}=ans 2xi=ans G o v e r = ∏ G x i Gover=\prod G_{x_i} Gover=Gxi的话,那么有
∑ i = 1 n ( G o v e r ( i , 0 ) − 1 ) ≤ k \sum_{i=1}^n (Gover(i,0)-1)\leq k i=1n(Gover(i,0)1)k
(减 1 1 1是因为有一种路径就是一直待在原地,但这不会被计算入答案)

那么我们肯定要求 a n s ans ans尽量大,那么我们从大开始枚举一个 k k k

若乘上 G k G_k Gk后满足条件就可以乘


c o d e code code

#include
#include
#include
#define ll long long
using namespace std;
const ll Size=125;
struct matrix{
	ll a[Size][Size];
}G[70],ove;
ll n,m,ans,k;
matrix operator *(matrix &a, matrix &b) {
	matrix c;memset(c.a,0,sizeof(c.a));
	for(ll i=0;i<Size;i++)
	  for(ll j=0;j<Size;j++)
	    for(ll k=0;k<Size;k++)
	      c.a[i][j]+=a.a[i][k]*b.a[k][j];
	return c;
}
bool check(matrix a){
	ll sum=0;
	for(ll i=1;i<=n;i++)
	  if(k<=(sum+=a.a[i][0]-1)) return 1;
	return 0;
} 
int main()
{
	scanf("%lld%lld%lld",&n,&m,&k);
	G[0].a[0][0]=1;
	for(ll i=1;i<=n;i++)
	  ove.a[i][i]=G[0].a[i][i+n]=G[0].a[i+n][i+2*n]=G[0].a[i][0]=1;
	for(ll i=1;i<=m;i++){
		ll x,y,w;
		scanf("%lld%lld%lld",&x,&y,&w);
		G[0].a[x+(w-1)*n][y]++;
	}
	ll tot=0;matrix tmp;
	while(++tot){
		if(tot>65)
		  return puts("-1")&0;
		G[tot]=G[tot-1]*G[tot-1];
		if(check(G[tot])) break;
	}
	while((--tot)>=0){
		tmp=ove*G[tot];
		if(!check(tmp))
		  ans+=(1ll<<tot),ove=tmp;
	}
	printf("%lld",ans);
}

你可能感兴趣的:(数论and数学,倍增,luogu,倍增,矩阵乘法,POI,数学)