poj 3613 Cow Relays【矩阵快速幂+Floyd】

!:自环也算一条路径
矩阵快速幂,把矩阵乘法的部分替换成Floyd(只用一个点扩张),这样每“乘”一次,就是经过增加一条边的最短路,用矩阵快速幂优化,然后因为边数是100级别的,所以把点hash一下最多剩下200个

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=205,inf=1e9;
int n,m,s,t,g[N],tot,x[N],y[N],z[N],h[1005],has;
struct jz
{
	int a[N][N];
	jz operator * (const jz &b) const
	{
		jz c;
		for(int i=1;i<=has;i++)
			for(int j=1;j<=has;j++)
				c.a[i][j]=inf;
		for(int k=1;k<=has;k++)
			for(int i=1;i<=has;i++)
				for(int j=1;j<=has;j++)
					c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
		return c;
	}
}a,r;
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&z[i],&x[i],&y[i]);
		g[++tot]=x[i],g[++tot]=y[i];
	}
	sort(g+1,g+1+tot);
	for(int i=1;i<=tot;i++)
		if(i==1||g[i]!=g[i-1])
			h[g[i]]=++has;
	for(int i=1;i<=has;i++)
		for(int j=1;j<=has;j++)
			a.a[i][j]=inf;
	for(int i=1;i<=m;i++)
		a.a[h[x[i]]][h[y[i]]]=a.a[h[y[i]]][h[x[i]]]=min(z[i],a.a[h[y[i]]][h[x[i]]]);//,cerr<<h[y[i]]<<" "<<h[x[i]]<<" "<<z[i]<<endl;
	s=h[s],t=h[t];
	r=a;
	n--;
	while(n)
	{
		if(n&1)
			r=r*a;
		a=a*a;
		n>>=1;
	}
	printf("%d\n",r.a[s][t]);
	return 0;
}
posted @ 2018-07-06 22:47  lokiii  阅读(170)  评论(0编辑  收藏  举报