矩阵加速优化最短路求调
查看原帖
矩阵加速优化最短路求调
526895
WYZ20030051楼主2023/8/23 14:55

用的纯矩阵做法,参考的这篇题解。调了一上午没调对,过不了样例

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<cstdlib>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int ll
int read()
{
	int now=0,nev=1;
	char c=getchar();
	while(c<'0' || c>'9')
	{
		if(c=='-')
			nev=-1;
		c=getchar();
	}
	while(c>='0' && c<='9')
	{
		now=(now<<1)+(now<<3)+(c&15);
		c=getchar();
	}
	return now*nev;
}
const int MAXN=110;
const int INF=1e18;
int n,m,k;
struct Matrix
{
	int t[MAXN][MAXN];
}rel,mag,ans;//松弛矩阵,魔法+松弛矩阵,记录答案的矩阵 
void init(Matrix a)
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(i==j)
				a.t[i][j]=0;
			else
				a.t[i][j]=INF;
		}
	}
}
void clear(Matrix a)
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
			a.t[i][j]=INF;
	}
}
Matrix mul(Matrix a,Matrix b)
{
	Matrix res;
	clear(res);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			for(int k=0;k<n;k++)
				res.t[i][j]=min(res.t[i][j],a.t[i][k]+b.t[k][j]);
		}
	}
	return res;
}
Matrix quickpow(Matrix a,ll k)
{
	Matrix res=a,b=a;
	k--;
	init(res);
	while(k)
	{
		if(k&1)
			res=mul(res,b);
		b=mul(b,b);
		k>>=1;
	}
	return res;
}
signed main()
{
	n=read(),m=read(),k=read();
	init(rel),init(mag);
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		x=read(),y=read(),z=read();
		x--,y--;
		rel.t[y][x]=min(rel.t[y][x],z);
		mag.t[y][x]=min(mag.t[y][x],-z);
	}
	rel=quickpow(rel,n);
	mag=mul(mag,rel);
	mag=quickpow(mag,k);
	ans=mul(mag,rel);
	printf("%lld",ans.t[n-1][0]);
	return 0;
}
2023/8/23 14:55
加载中...