【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑
生活随笔
收集整理的這篇文章主要介紹了
【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【題意】給定m條邊的無向圖,起點s,終點t,要求找出s到t恰好經過n條邊的最短路徑。n<=10^6,m<=100。
【算法】floyd+矩陣快速冪
【題解】
先對點離散化,得到點數N。
對初始邊建立初始矩陣,然后考慮每次多跑一條邊相當于一次矩陣乘法,即c[i][j]=min(a[i][k],a[k][j]),k=1~N。
定義了矩陣乘法,就可以用矩陣快速冪優化了。
初始矩陣ans[i][i]=0,轉移矩陣a[i][i]=inf,這樣就是恰好n條邊。(如果a[i][i]=0就是<=n條邊)
復雜度O(N^3*log n)。
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> using namespace std; const int N=210;//òa?aá?±??£ typedef int mat[N][N]; mat a,c,ans; int n,m,s,t,cnt=0,z[1010]; int read() {char c;int s=0,t=1;while(!isdigit(c=getchar()))if(c=='-')t=-1;do{s=s*10+c-'0';}while(isdigit(c=getchar()));return s*t; } void mul(mat a,mat b){memset(c,0x3f,sizeof(c));for(int i=1;i<=cnt;i++){for(int j=1;j<=cnt;j++){//ioíjò??ùò2ê??éò?è?ò?è|??à′μ??£ for(int k=1;k<=cnt;k++)c[i][j]=min(c[i][j],a[i][k]+b[k][j]);}}for(int i=1;i<=cnt;i++)for(int j=1;j<=cnt;j++)a[i][j]=c[i][j]; } int main(){n=read();m=read();s=read();t=read();memset(a,0x3f,sizeof(a));for(int i=1;i<=m;i++){int w=read(),u=read(),v=read();//è¨?μ?úμúò???£?£?£? if(!z[u])z[u]=++cnt;if(!z[v])z[v]=++cnt;u=z[u];v=z[v];a[u][v]=a[v][u]=min(a[u][v],w);}memset(ans,0x3f,sizeof(ans));for(int i=1;i<=cnt;i++)ans[i][i]=0;while(n){if(n&1)mul(ans,a);mul(a,a);n>>=1;}printf("%d",ans[z[s]][z[t]]);return 0; } View Code?
轉載于:https://www.cnblogs.com/onioncyc/p/7590255.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringCloud(第 016 篇)
- 下一篇: 【NetApp】NetBoot的使用方法