BZOJ1706奶牛接力跑
生活随笔
收集整理的這篇文章主要介紹了
BZOJ1706奶牛接力跑
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這個東西思路還是不錯的。
解法就是把矩陣冪的加法改成取min,乘法改成加法就好,和floyed是一樣的。這樣的話,矩陣操作一次就相當于松弛了一次最短路。
建矩陣的過程也比較簡單,可以離散化,當然下面有另一種更優秀的打法,可以借鑒一下。
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<cstdio> #include<vector> #include<set> #include<map> #include<queue> #include<stack> using namespace std; int read(){int sum=0,f=1;char x=getchar();while(x<'0'||x>'9'){if(x=='-') f=-1;x=getchar();}while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}return sum*f; } int k,m,s,e,num; int id[2000]; struct Matrix{int x[600][600];void add(int a,int b,int c){x[a][b]=c;return ;}friend Matrix operator * (Matrix a,Matrix b){Matrix c;memset(c.x,0x3f,sizeof(c.x));for(int i=1;i<=num;i++)for(int j=1;j<=num;j++)for(int k=1;k<=num;k++)c.x[i][j]=min(c.x[i][j],a.x[i][k]+b.x[k][j]);return c;}void db(){cout<<endl;for(int i=1;i<=num;i++){for(int j=1;j<=num;j++)cout<<x[i][j]<<" ";cout<<endl;}}void put(int a,int b){printf("%d",x[a][b]);return ;} }a; void qpow(int k){Matrix c=a,b=a; // b.db();for(;k;k>>=1,b=b*b)if(k&1) c=c*b; // c.db();a=c; } int main(){k=read();m=read();s=read();e=read();memset(a.x,0x3f,sizeof(a.x));for(int i=1,x,y,z;i<=m;i++){z=read();x=read();y=read();id[x]=id[x]?id[x]:++num;id[y]=id[y]?id[y]:++num;a.add(id[x],id[y],z);a.add(id[y],id[x],z);} // a.db();qpow(k-1); // a.db(); a.put(id[s],id[e]);return 0; } View Code這種打法是直接用a做的初始矩陣,根據An=A*An-1做的操作,因為一開始不太清楚單位矩陣是誰。
后來想通了,以前的單位矩陣之所以是那樣的,是因為單位矩陣的定義是另一個矩陣乘完該矩陣還是原矩陣,以前的之所以是對角線全是1,是因為通過矩陣乘后這個矩陣可以滿足單位矩陣性質。
那么這個題的單位矩陣是正無窮矩陣,因為該任何一個矩陣乘完該矩陣還是原矩陣(因為取min嘛)。
轉載于:https://www.cnblogs.com/Yu-shi/p/11203002.html
總結
以上是生活随笔為你收集整理的BZOJ1706奶牛接力跑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7月17日每日一答
- 下一篇: 父类作为方法的形参以及父类作为方法返回值