很明显,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位即可
}
}

京公网安备 11010502036488号