其他分享
首页 > 其他分享> > [JLOI2011]飞行路线

[JLOI2011]飞行路线

作者:互联网

题目链接:点这里
题解:这个题是一个很明显的分层图问题,我们要建立k+1层图,从代表从这一层到上一层免费,即代表用了一次的免费机会,所以我们最后是要求在第k层的终点,即代表已经用了这k次的免费机会。而且这个题数据相当毒瘤,我们还需要建立终点各个层的图,因为有可能最短的数据是没有用完这k次机会的(这数据绝了)。

#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
#define endl "\n"

using namespace std;

const int maxn = 5e5 + 5;

struct node
{
    ll to, next, w;
} e[maxn*20];
bool f[maxn*10];
ll cnt = 1;
ll head[maxn*20];
ll d[maxn * 20];
void add(ll u,ll v,ll w)
{
    e[cnt] = {v, head[u], w};
    head[u] = cnt++;
}
void dis(int t)
{
    memset(d, 0x3f, sizeof d);
    memset(f, 0, sizeof f);
    priority_queue<pr, vector<pr>, greater<pr> > q;
    d[t] = 0;
    q.push({0, t});
    while(q.size())
    {
        int a = q.top().second;
        q.pop();
        if(f[a])
            continue;
        f[a] = 1;
        for (int i = head[a]; i; i = e[i].next)
        {
            int v = e[i].to, w = e[i].w;
            if(d[v]>d[a]+w)
            {
                d[v] = d[a] + w;
                q.push({d[v], v});
            }
        }
    }
}
int main()
{
    int n, m, k;
    cin >> n >> m >> k;
    int u1, v1;
    cin >> u1 >> v1;
    for (int i = 1; i <= m;i++)
    {
        int u, v, w;
        cin >> u >> v >> w;
        for (int j = 0; j <= k;j++)
        {
            add(u + j * n, v + j * n, w);
            add(v + j * n, u + j * n, w);
        }
        for (int j = 1; j <= k;j++)
        {
            add(u + (j-1) * n, v + (j) * n, 0);
            add(v + (j-1) * n, u + (j) * n, 0);
        }
    }
    for (int j = 1; j <= k;j++)
    {
        add(v1 + (j-1) * n, v1 + (j) * n, 0);
    }
    dis(u1);
    cout << d[(k) * n + v1];
}


另外几道类似的题目 :这里 这里

标签:head,JLOI2011,int,ll,路线,add,飞行,maxn,define
来源: https://blog.csdn.net/weixin_45684937/article/details/116905133