[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