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