很明显,n最大100,floyd算法可以胜任o(Cn^3)复杂度,c是高精度的系数。
当然用堆优化的迪克特斯拉或者spfa都可以秒了此题。显然我懒(不是)。
具体用到有高精+高精,高精*单精,高精比较高精;
#include<iostream> #include<cstdio> #define rep(i,a,b) for(int i=a;i<=b;i++) #define rap(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int maxn=105,mod=1e5; int pow2[505][51]={1},map[maxn][maxn][51];//pow2储存2^k次方 void power(int m)//计算需要用到的2^k次方 { rep(i,1,m){ int car=0; rep(j,0,50){ pow2[i][j]=pow2[i-1][j]*2+car; car=pow2[i][j]/mod; pow2[i][j]%=mod; } } } inline void _plus(int*a,int*b,int*c)//高精+高精 { int car=0; rep(i,0,50){ a[i]=b[i]+c[i]+car; car=a[i]/mod; a[i]%=mod; } } inline void _min(int*a,int*b)//高精比高精 { rap(i,50,0){ if(a[i]>b[i]){ rep(j,0,50) a[j]=b[j]; return; } else if(a[i]<b[i])return; } } inline void write(int*a)//这个是我调试用的 { int k=0; rap(i,50,0) if(a[i]){ k=i; break; } printf("%d",a[k]); rap(i,k-1,0) printf("%05d",a[i]); puts(""); } int main() { int n,m; cin>>n>>m; power(m); // rep(i,0,m)write(pow2[i]); rap(i,50,0){ if(pow2[500][i]){ cout<<i<<endl; break; } } rep(i,0,n-1) rep(j,0,n-1) map[i][j][50]=1;//因为最大不会大到5*50位数,可以将倒数第5位标定1,记为无穷 rep(i,0,m-1){ int a,b; cin>>a>>b; if(!map[a][b][0]){//防止重边 rep(j,0,50) map[a][b][j]=map[b][a][j]=pow2[i][j]; map[a][b][50]=map[b][a][50]=0;//去掉无穷标记 } } rep(i,0,n-1)//floyd算法 rep(j,0,n-1) rep(k,0,n-1){ int tmp[81]; _plus(tmp,map[j][i],map[i][k]); _min(map[j][k],tmp); } rep(i,1,n-1){ if(map[0][i][50])puts("-1");//被标记的话不可通,输出-1 else printf("%d\n",map[0][i][0]);//否则因为取模1e5,直接输出0位即可 } }