USACO09FEB 改造路Revamping Trails(分层图模板)

满分做法:

因为\(k\)很小,所以把每个点拆出\(k\)个点,对应使了多少个高速,这个就是分层图了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxm=3000007;
int n,m,k;
int pre[maxm<<1],last[maxm],len[maxm<<1],other[maxm<<1],l;
ll dis[maxm];
bool vis[maxm];
priority_queue<pair<ll,int> >q;
ll ans;
void add(int x,int y,int z)
{
 l++;
 pre[l]=last[x];
 last[x]=l;
 other[l]=y;
 len[l]=z;
}
void dijkstra()
{
 for(int i=1;i<=(k+1)*n;i++)
 dis[i]=1e14+7;
 dis[1]=0;
 q.push(make_pair(0,1));
 while(q.size())
 {
  int u=q.top().second;
  q.pop();
  if(vis[u]) continue;
  vis[u]=1;
  for(int p=last[u];p;p=pre[p])
  {
   int v=other[p];
   if(dis[v]>dis[u]+len[p])
   {
     dis[v]=dis[u]+len[p];
     q.push(make_pair(-dis[v],v));
   }
  }
 }
}
int main()
{
 scanf("%d%d%d",&n,&m,&k);
 for(int i=1;i<=m;i++)
 {
   int x,y,z;
   scanf("%d%d%d",&x,&y,&z);
   add(x,y,z);
   add(y,x,z);
   for(int j=1;j<=k;j++)
   {
     add(j*n+x,j*n+y,z);
     add(j*n+y,j*n+x,z);
     add((j-1)*n+x,j*n+y,0);
     add((j-1)*n+y,j*n+x,0);
   }
 }
 dijkstra();
 ans=dis[n];
 for(int j=1;j<=k;j++)
 {
   ans=min(ans,dis[j*n+n]);
 }
 printf("%lld\n",ans);
 return 0;
}

原文地址:https://www.cnblogs.com/lihan123/p/11832712.html

时间: 2024-10-10 19:01:30

USACO09FEB 改造路Revamping Trails(分层图模板)的相关文章

luoguP2939 [USACO09FEB]改造路Revamping Trails

约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到牧场N去给奶牛检查身体. 通过每条小径都需要消耗一定的时间.约翰打算升级其中K条小径,使之成为高 速公路.在高速公路上的通行几乎是瞬间完成的,所以高速公路的通行时间为0. 请帮助约翰决定对哪些小径进行升级,使他每天早上到牧场W花的时间最少.输出这个最少 的时间. 分层图DP,启发良多 1.远离SPFA,Dijstra+堆稳定多了 2.要在Dijstra中Dp,堆中必须包含三要素:当前点.层数.距离,缺一

P2939 [USACO09FEB]改造路Revamping Trails

传送门 显然的分层图 设 dis [ i ] [ j ] 表示到点 i , 已经建立了 j 条高速公路的最短距离 然后转移每次都分建立高速公路和不建立高速公路两种情况 跑Djikstra #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> using namespace std

【分层图最短路,dijstra】P2939 [USACO09FEB]改造路Revamping Trails

1 #include<iostream> 2 #include<string> 3 #include<queue> 4 #include<stack> 5 #include<vector> 6 #include<map> 7 #include<cstdio> 8 #include<cstdlib> 9 #include<algorithm> 10 #include<set> 11 #in

[USACO09FEB]改造路Revamping Trails

题目描述 Farmer John dutifully checks on the cows every day. He traverses some of the M (1 <= M <= 50,000) trails conveniently numbered 1..M from pasture 1 all the way out to pasture N (a journey which is always possible for trail maps given in the test

【luogu P2939 [USACO09FEB]改造路Revamping Trails】 题解

题目链接:https://www.luogu.org/problemnew/show/P2939 本来说是双倍经验题,跟飞行路线一样的,结果我飞行路线拿deque优化SPFA过了这里过不了了. 所以多学一种优先队列优化. #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define ll long lon

【USACO09FEB】改造路Revamping Trails

链接 显而易见的 dp 方程,dp [ x ] [ i ] 表示到达点 x 免费了 i 条边的最短时间. dp [ x ] [ i ] = min ( dp [ pre ] [ i - 1 ] , dp [ pre ] [ i ] + dis [ pre ] [ x ] ) ; 如果直接跑dp,得搞个拓扑图,并且环上信息不会统计. 考虑分层图,然后就是一个分层图模板了. (回家画个图) 1 #include<cstdio> 2 #include<string> 3 #include

P2939 [USACO09FEB]改造路[分层图最短路]

题意翻译 约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到牧场N去给奶牛检查身体. 通过每条小径都需要消耗一定的时间.约翰打算升级其中K条小径,使之成为高 速公路.在高速公路上的通行几乎是瞬间完成的,所以高速公路的通行时间为0. 请帮助约翰决定对哪些小径进行升级,使他每天从1号牧场到第N号牧场所花的时间最短 解析 提高练习场看到这题,瞄一眼,诶,这不是分层图裸题吗??? [啥是分层图] 分层图,简单来说,就是把一张图复制多次,分为多份,每层图代表一种

[黑科技]分层图

最近几天写了一些分层图的题目,来总结一下 分层图有一个很重要的性质:上一层不能到达下一层,但下一层能到达上一层 分层图常常结合最短路,所以叫分层图最短路,当然,也结合缩点之类的 [USACO09FEB]改造路Revamping Trails 双倍经验题[JLOI2011]飞行路线 这是一道分层图最短路裸题 考虑\(dp\),\(dis[i][j]\)表示到达第\(i\)个点已经\(j\)次升级后所经过的最短路径 那么就可以愉快的在\(Dijkstra\)里分类讨论一下 \(Code\ Below

Bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 dijkstra,堆,分层图

1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1573  Solved: 428[Submit][Status][Discuss] Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N;