zoukankan      html  css  js  c++  java
  • bzoj2763 [JLOI2011]飞行路线

    Description

    (Alice)(Bob) 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在 (n) 个城市设有业务,设这些城市分别标记为 (0)(n-1),一共有 (m) 种航线,每种航线连接两个城市,并且航线有一定的价格。 (Alice)(Bob) 现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么 (Alice)(Bob) 这次出行最少花费多少?

    Input

    数据的第一行有三个整数, (n,m,k) ,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数, (s,t) ,分别表示他们出行的起点城市编号和终点城市编号。 ((0le s,t<n))
    接下来有 (m) 行,每行三个整数, (a,b,c) ,表示存在一种航线,能从城市 (a) 到达城市 (b) ,或从城市 (b) 到达城市 (a) ,价格为 (c) 。( (0le a,b<n,a)(b) 不相等, (0le cle 1000) )

    Output

    只有一行,包含一个整数,为最少花费。

    Sample Input

    5 6 1
    0 4
    0 1 5
    1 2 5
    2 3 5
    3 4 5
    2 3 3
    0 2 100

    Sample Output

    8

    HINT

    对于 (100\%) 的数据, (2le nle 10000,1le mle 50000,0le kle 10) .

    Solution

    分层图最短路裸题,用优先队列去除后效性,可用于套版。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define N 100001
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define fech(i, x) for (int i = 0; i < x.size(); i++)
    #define ll long long
    
    inline int read() {
        int x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); }
        while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag;
    }
    
    int n, m, k, S, T;
    struct edge { int u, v, w; } eg[N]; int tot;
    vector<int> g[N];
    int d[N][11];
    bool vis[N][11];
    
    struct node {
    	int u, d, f;
    	bool operator < (const node& b) const { return d > b.d; }
    };
    priority_queue<node> q;
    
    void bfs() {
    	memset(d, 127, sizeof d); d[S][0] = 0;
    	q.push(node { S, 0, 0 });
    	while(!q.empty()) {
    		node x = q.top(); q.pop();
    		int u = x.u, dis = x.d, f = x.f;
    		if(!(u ^ T)) { cout << dis; exit(0); }
    		if(vis[u][f]) continue;
    		vis[u][f] = 1;
    		fech(i, g[u]) {
    			edge e = eg[g[u][i]];
    			if(f < k && !vis[e.v][f + 1] && d[e.v][f + 1] > dis) d[e.v][f + 1] = dis, q.push(node{ e.v, dis, f + 1 });
    			if(!vis[e.v][f] && d[e.v][f] > dis + e.w) d[e.v][f] = dis + e.w, q.push(node{ e.v, dis + e.w, f });
    		}
    	}
    }
    
    int main() {
    	scanf("%d%d%d%d%d", &n, &m, &k, &S, &T);
    	while(m--) {
    		int u = read(), v = read(), w = read();
    		eg[++tot] = edge { u, v, w }; g[u].push_back(tot);
    		eg[++tot] = edge { v, u, w }; g[v].push_back(tot);
    	}
    	bfs();
    }
    
  • 相关阅读:
    【洛谷P5158】 【模板】多项式快速插值
    【洛谷P4245】 【模板】任意模数NTT
    【洛谷4781】 【模板】拉格朗日插值
    BZOJ 3625:小朋友和二叉树 多项式开根+多项式求逆+生成函数
    【洛谷】5205 【模板】多项式开根
    nowcoder73E 白兔的刁难 单位根反演+NTT
    BZOJ 3328: PYXFIB 单位根反演+矩阵乘法+二项式定理
    loj #6485. LJJ 学二项式定理 单位根反演
    Struts 2 框架搭建HelloWorld
    Struts 2 概念介绍
  • 原文地址:https://www.cnblogs.com/aziint/p/8416391.html
Copyright © 2011-2022 走看看