cf gym 102222F Moving On

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值