其他分享
首页 > 其他分享> > Cow relays

Cow relays

作者:互联网

给定一张无向图 求S->T经过K条边的最短路是多少

对于形如 \(A(i,j)=opt(A(i,k)\ opt\ B(k,j)\)的形式 可以考虑用矩阵乘法来解决

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int N=110;
int read()
{
	int x=0,f=0,c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f?-x:x;
}
 
struct Node
{
	int x,y,val;
}p[N];
int b[N*2],tot;

struct Martix
{
	int x,y;
	int d[N][N];
	Martix(int tx,int ty){x=tx; y=ty; memset(d,0x3f,sizeof d);}
	void Unit(){ for(int i=1;i<=x;i++) d[i][i]=0;}
};

Martix operator*(const Martix &A,const Martix &B)
{
	Martix ret(A.x,B.y);
	for(int i=1;i<=A.x;i++)
		for(int j=1;j<=B.y;j++)
			for(int k=1;k<=A.y;k++)
				ret.d[i][j]=min( ret.d[i][j], A.d[i][k]+B.d[k][j] );
	return ret;
}
Martix ksm(Martix A,int b)
{
	Martix ans(A.x,A.y);  ans.Unit();
	while(b)
	{
		if(b&1) ans=A*ans;
		A=A*A;
		b=b>>1;
	}
	return ans;
}

int k,m,S,T;
int main()
{
	k=read(); m=read(); S=read(); T=read();
	for(int i=1;i<=m;i++)
	{
		int z=read(),x=read(),y=read();
		p[i]=(Node){x,y,z};
		b[++tot]=x; b[++tot]=y;
	}
	sort(b+1,b+tot+1);
	tot=unique(b+1,b+tot+1)-(b+1);
	
	Martix A(tot,tot);
	for(int i=1;i<=m;i++)
	{
		int x=lower_bound(b+1,b+tot+1,p[i].x)-b;
		int y=lower_bound(b+1,b+tot+1,p[i].y)-b;
		A.d[x][y]=A.d[y][x]=p[i].val;
	}
	S=lower_bound(b+1,b+tot+1,S)-b;
	T=lower_bound(b+1,b+tot+1,T)-b;
	Martix ans=ksm(A,k);
	printf("%d",ans.d[S][T]);
	return 0;
}

特别要注意的是:
对于一个邻接矩阵,d[i][i]的赋值问题 要判断是否允许从i到i保持不动 这个地方必须强制离开 所以d[i][i]不能赋值为0 需要特殊考虑

标签:opt,Cow,int,long,read,include,relays,getchar
来源: https://www.cnblogs.com/juruoHBr/p/15781759.html