BZOJ1706&&洛谷P2886 [usaco2007 Nov]relays 奶牛接力跑

emm,看着很难。。

我们发现边一共100条那么点最多也就200个,所以我们将点离散化到1~200

然后我们想到,从一个点到另一个点走k条路的方案可以用矩阵加速,那么最短路是不是也可以呢?然后我们想到矩阵可以加速的东西必须满足可以使用结合/交换律,发现最短路符合,所以我们将运算方法重新定义一下,+->min,*->+

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
struct mtix
{
	int w[250][250];
	mtix(){memset(w,0x3f,sizeof(w));}
}a,b;
int t,m,cnt=0,st,ed;
int id[1050];
mtix mul(mtix e,mtix f)
{
	mtix c;
	for (int k=1;k<=cnt;k++)
		for (int i=1;i<=cnt;i++)
			for (int j=1;j<=cnt;j++)
			c.w[i][j]=min(c.w[i][j],e.w[i][k]+f.w[k][j]);
	return c;
}
mtix mpow(int y)
{
	for (;y;a=mul(a,a),y>>=1)
		if (y&1) b=mul(b,a);
	return b;
}
int main()
{
	t=read();m=read();st=read();ed=read();
	for (int i=1;i<=m;i++)
	{
		int x,y,z;z=read(),x=read(),y=read();
		if (!id[x]) id[x]=++cnt;
		if (!id[y]) id[y]=++cnt;
		a.w[id[x]][id[y]]=a.w[id[y]][id[x]]=z;
	}
	for (int i=1;i<=cnt;i++) b.w[i][i]=0;
	mtix ans=mpow(t);
	cout<<ans.w[id[st]][id[ed]];
	return 0;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80880212
今日推荐