bzoj2165 -- 倍增floyd

来源:互联网 发布:手机虚拟试衣软件 编辑:程序博客网 时间:2024/05/29 03:36
题意:给定一张有向图,求图中从1开始长度>=m且边数最少的路径经过的边数。

 

考虑倍增floyd。

令f[p][i][j]表示经过2p条边从i到j的最大长度。

那么f[p][i][j]=max{f[p-1][i][k]+f[p-1][k][j]}

令g[i][j]表示当前答案从i到j的最大长度。

求答案时从大到小枚举每个二进制位,更新g,若不存在从1开始长度>=m的路径,这一位就是1。

 

代码:

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1ll<<62) 7 #define N 110 8 #define M 70 9 #define ll long long10 ll m,f[M][N][N],A[N][N],t[N][N],Ans;11 int i,j,k,n,p,T;12 inline ll Max(ll x,ll y){return x<y?y:x;}13 inline void Init(){14     memset(f,0xef,sizeof(f));15     memset(A,0xef,sizeof(A));16     Ans=0;17 }18 int main(){19     scanf("%d",&T);20     while(T--){21         scanf("%d%lld",&n,&m);22         Init();23         for(i=1;i<=n;i++)24         for(j=1;j<=n;j++){25             scanf("%lld",&f[0][i][j]);26             if(f[0][i][j]==0)f[0][i][j]=-INF;27         }28         for(p=1;1ll<<p<=m;p++){29             for(k=1;k<=n;k++){30                 for(i=1;i<=n;i++){31                     for(j=1;j<=n;j++){32                         f[p][i][j]=Max(f[p][i][j],f[p-1][i][k]+f[p-1][k][j]);33                         if(i==1&&f[p][i][j]>=m)break;34                     }35                     if(j<=n)break;36                 }37                 if(i<=n)break;38             }39             if(k<=n)break;40         }41         for(i=1;i<=n;i++)A[i][i]=0;42         while(p--){43             memset(t,0xef,sizeof(t));44             for(k=1;k<=n;k++){45                 for(i=1;i<=n;i++){46                     for(j=1;j<=n;j++){47                         t[i][j]=Max(t[i][j],f[p][i][k]+A[k][j]);48                         if(i==1&&t[i][j]>=m)break;49                     }50                     if(j<=n)break;51                 }52                 if(i<=n)break;53             }54             if(k>n){55                 memcpy(A,t,sizeof(A));56                 Ans+=1ll<<p;57             }58         }59         printf("%lld\n",Ans+1);60     }61     return 0;62 }
bzoj2165

 

原创粉丝点击