1. 程式人生 > WINDOWS開發 >AcWing345 牛站(floyd+倍增)

AcWing345 牛站(floyd+倍增)

設計狀態為走了k步,從i-j的最短路,由於加法滿足結合律,因此可以用倍增來優化逼近n

這樣可以log複雜度逼近,程式碼與floyd相似,但是狀態的定義完全不同,本題還需要離散化一下,因為原數太大

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
const int N=210;
int g[N][N];
int res[N][N];
int n,t,s,e;
int cnt;
void mul(int c[][N],int a[][N],int b[][N]){
    int tmp[N][N];
    memset(tmp,0x3f,sizeof
tmp); int i,j,k; for(k=1;k<=cnt;k++){ for(i=1;i<=cnt;i++){ for(j=1;j<=cnt;j++){ tmp[i][j]=min(tmp[i][j],a[i][k]+b[k][j]); } } } memcpy(c,tmp,sizeof tmp); } void qmi(){ memset(res,sizeof res); for(int i=1;i<N;i++) res[i][i]
=0; while(n){ if(n&1){ mul(res,res,g); } mul(g,g,g); n>>=1; } } int main(){ memset(g,sizeof g); cin>>n>>t>>s>>e; int i; map<int,int> id; cnt=1; if(!id.count(s)) id[s]=cnt++;
if(!id.count(e)) id[e]=cnt++; s=id[s]; e=id[e]; for(i=1;i<=t;i++){ int a,b,c; scanf("%d%d%d",&c,&a,&b); if(!id.count(a)) id[a]=cnt++; if(!id.count(b)) id[b]=cnt++; a=id[a],b=id[b]; g[a][b]=g[b][a]=min(g[a][b],c); } cnt--; qmi(); printf("%d\n",res[s][e]); }
View Code