[JLOI2011]飞行路线

思路:

一道最短路的题。。。

分层最短路的板子。。。

对于图中的所有节点 u u u,他可以拆成 k + 1 k + 1 k+1个节点 u j u_j uj,而且j ∈ \in [0,k]。

分别表示当使用 j j j 次免费通行权限后到达 u u u 号节点的状态。

对于,样例来说那个图的话(脑补)加工中

list[i][j]为到达i用了j次免费机会的最小花费。

vis[i][j]为到达i用了j次免费机会的情况是否出现过。

对于某些路径,我们可以选择使用机会,也可以选择不使用机会。

之后就分两种情况 :

void spfa() {
    int head = 1;
	int tail = 2;
    memset(list, 0 ,sizeof(list));
    list[1][0] = ks;
	list[1][1] = 0;
    while(head != tail) {
        int x = list[head][0];
		int c = list[head][1];
        for(int k = last[x];k;k = a[k].next) {
            int y = a[k].y;
            if(f[x][c] + a[k].dis < f[y][c]) {
                f[y][c] = f[x][c] + a[k].dis;
                if(vis[y][c] == false) {
                    vis[y][c] = true;
                    list[tail][0] = y;
                    list[tail][1] = c;
                    tail ++;
					if(tail == a_b) {
						tail = 1;
					}
                }
            }
            if(f[x][c] < f[y][c + 1] && c < d_k) {
                f[y][c + 1] = f[x][c];
                if(vis[y][c + 1] == false) {
                    vis[y][c + 1] = true;
                    list[tail][0] = y;
                    list[tail][1] = c + 1;
                    tail ++;
					if(tail == a_b){
						tail = 1;
					}
                }
            }
        }
        head ++;
		if(head == a_b) {
			head = 1;
		}
        vis[x][c] = false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值