http://codeforces.com/gym/102222/problem/F
floyed好题,我们对每个点的危险值进行排序,然后只能让前dp[k][i][j]表示前k个点允许走的情况下,最短路的状态
对于每个询问就是找到危险值较大的那个城市 id 得到dp[id][u][v]的值。
#include<bits/stdc++.h>
namespace fastIO
{
#define BUF_SIZE 100000
bool IOerror = 0;
inline char nc()
{
static char buf[BUF_SIZE];
static char *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend)
{
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1)
{
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline int rd(int &x)
{
char ch;
while(blank(ch = nc()));
if(IOerror) return -1;
for(x=ch-'0';(ch=nc())>='0' && ch<='9';x=x*10+ch-'0');
return 1;
}
#undef BUF_SIZE
};
using namespace fastIO;
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn=321;
int f[maxn][maxn][maxn];
int danger[maxn];
int id[maxn];
bool cmp(int a,int b){return danger[a]<danger[b];}
int n, m, T, q;
int main()
{
int cas=0;
//scanf("%d",&T);
rd(T);
while(T--)
{
//scanf("%d %d",&n,&q);
rd(n);rd(q);
for(int i = 1; i <= n; ++i)
{
id[i] = i;
//scanf("%d",&danger[i]);
rd(danger[i]);
}
sort(id+1, id+1+n, cmp);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
// scanf("%d",&f[i][j][0]);
rd(f[0][i][j]);
for(register int k = 1; k <= n; ++k)
for(register int i = 1; i <= n; ++i)
for(register int j = 1; j <= n; ++j)
if(i!=j)
f[k][i][j] = min(f[k-1][i][j], f[k-1][i][id[k]]+f[k-1][id[k]][j]);
printf("Case #%d:\n",++cas);
while(q--)
{
int u, v ,w;
//scanf("%d%d%d",&u,&v,&w);
rd(u);rd(v);rd(w);
int ans = 0;
for(register int i = n; i >=0; --i)
{
if(danger[id[i]]<=w)
{
ans = i;
break;
}
}
printf("%d\n",f[ans][u][v]);
}
}
return 0;
}