BZOJ 1706: [usaco2007 Nov]relays 奶牛接力跑 倍增Floyd

时间:2023-03-10 07:26:18
BZOJ 1706: [usaco2007 Nov]relays 奶牛接力跑  倍增Floyd

题不难,但是一开始把读入看错了,调了半天qaq~

Code:

#include <bits/stdc++.h>
#define N 300
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
map<int,int>pp;
int n,m,S,T,tot,dis[N][N][30],tmp[N][N],g[N][N];
int main()
{
int i,j,k,l;
// setIO("input");
scanf("%d%d%d%d",&n,&m,&S,&T);
memset(dis,0x3f,sizeof(dis));
for(i=1;i<=m;++i)
{
int a,b,c;
scanf("%d%d%d",&c,&b,&a);
if(!pp[a]) pp[a]=++tot;
if(!pp[b]) pp[b]=++tot;
a=pp[a],b=pp[b];
dis[a][b][0]=dis[b][a][0]=min(dis[a][b][0],c);
}
if(!pp[S]) pp[S]=++tot;
if(!pp[T]) pp[T]=++tot;
S=pp[S],T=pp[T];
for(l=1;l<=20;++l)
{
for(k=1;k<=tot;++k)
for(i=1;i<=tot;++i)
for(j=1;j<=tot;++j)
dis[i][j][l]=min(dis[i][j][l], dis[i][k][l-1]+dis[k][j][l-1]);
}
memset(tmp,0x3f,sizeof(tmp));
int flag=0;
for(l=0;(1<<l)<=n;++l)
{
if(n&(1<<l)) // 2^l
{
if(flag==0)
{
flag=1;
for(i=1;i<=tot;++i)
for(j=1;j<=tot;++j) tmp[i][j]=dis[i][j][l];
}
else
{
memset(g,0x3f,sizeof(g));
for(k=1;k<=tot;++k)
{
for(i=1;i<=tot;++i)
{
for(j=1;j<=tot;++j)
{
g[i][j]=min(g[i][j], tmp[i][k]+dis[k][j][l]);
}
}
}
for(i=1;i<=tot;++i)
for(j=1;j<=tot;++j) tmp[i][j]=g[i][j];
}
}
}
printf("%d\n",tmp[S][T]);
return 0;
}