Luogu P5122 [USACO18DEC]Fine Dining 最短路

先跑一遍n为起点最短路,再新开一个点,向有干草垛的点连一根边权为d[u]-w的有向边(很重要。。我当时连的无向边,然后我死了。),相当于用价值抵消一部分边权,

然后以这个新的点为起点跑最短路就好了。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define pc(x) putchar(x)
#define R register int
using namespace std;
const int N=50010,M=100010;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m,k,cnt;
int vr[M<<1],nxt[M<<1],w[M<<1],fir[N],d[N],f[N];
bool vis[N];
priority_queue<pair<int,int> > q;
inline void add(int u,int v,int ww) {vr[++cnt]=v,w[cnt]=ww,nxt[cnt]=fir[u],fir[u]=cnt;}
inline void dijk() {
    memset(d,0x3f,sizeof(int)*(n+2)); d[n]=0,q.push(make_pair(0,n));
    while(q.size()) {
        R u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true;
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(d[v]>d[u]+w[i]) d[v]=d[u]+w[i],q.push(make_pair(-d[v],v));
        }
    }
}
inline void dijk2() {
    memset(f,0x3f,sizeof(int)*(n+3)); f[n+1]=0,q.push(make_pair(0,n+1));
    memset(vis,false,sizeof(bool)*(n+3)); while(q.size()) {
        R u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true;
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(f[v]>f[u]+w[i]) f[v]=f[u]+w[i],q.push(make_pair(-f[v],v));
        }
    }
}
signed main() {
    n=g(),m=g(),k=g(); for(R i=1,u,v,w;i<=m;++i) u=g(),v=g(),w=g(),add(u,v,w),add(v,u,w);
    dijk(); for(R i=1,u,w;i<=k;++i) u=g(),w=g(),add(n+1,u,d[u]-w); dijk2();
    for(R i=1;i<n;++i) f[i]<=d[i]&&d[i]!=0x3f3f3f3f?(pc(‘1‘),pc(‘\n‘)):(pc(‘0‘),pc(‘\n‘));
}


2019.04.24

原文地址:https://www.cnblogs.com/Jackpei/p/10765821.html

时间: 2024-08-30 11:57:31

Luogu P5122 [USACO18DEC]Fine Dining 最短路的相关文章

【题解】Luogu P1613 跑路 倍增+最短路

题里都说了$2^k$,明显倍增 因为跑路器的存在,不能直接跑最短路的原因: 如图,如果直接最短路从1号点到5号点的距离为3,需要3秒 而实际上走$1->5$这条边,因为$8=2^3$,只需1秒 $n≤50$直接无脑floyed随便跑 code 1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define ll long long 5 const int maxn=1e6+10; 6 inli

[Luogu P2891/POJ 3281/USACO07OPEN ]吃饭Dining

传送门:https://www.luogu.org/problemnew/show/P2891 题面 \ Solution 网络流 先引用一句真理:网络流最重要的就是建模 今天这道题让我深有体会 首先,观察数据范围,n=100,一般这种100-1000的图论题,很有可能是网络流. 那就直接从网络流的角度入手 考虑这样建模 建模要点如下: 1.建权值为1的边,保证每个食物和水仅用一次  2.没了 对以上的图求一个最大流,那不就是我们想要的最大的匹配数吗? 看起来是不是很OjbK? 其实不然,这样子

The 10 Best Neighborhoods in Seattle

https://www.seattlemet.com/articles/2015/4/24/the-10-best-neighborhoods-in-seattle-may-2015 By Darren Davis  4/24/2015 at 3:00pm  Published in the May 2015 issue of Seattle Met 2413 IMAGE: DOUG CHAYKA THE CONDO CRAZE Capitol Hill 27% own  •  73% rent

FOOD

Serving order of food courses(上菜顺序)1. Appetizer(starter)2. Main Course3. Dessert Style of cooking1. fry 2.steam 3.stew(炖,煨;) 4.roast(烤) 5.boil 6.BBQ(barbecue烧烤) 7.bake 8.stir-fry(炒,用旺火炒) Description of taste of food(texture and flavour口感和味道)1. sour 2

A*和IDA*介绍

\(A*\)算法是一种很神奇的搜索方法,它属于启发式搜索中的一种.A最主要的功能当然就是用来剪枝,提高搜索的效率.A主要的实现方法是通过一个估价函数,每次对下一步进行一个估价,根据估价出的值来决定下一步往哪走.因此,**估价函数的好坏决定了A*算法的优劣**. 估价函数分为三种情况: 如果估计的距离小于到目标状态的实际距离,这种情况下,搜索的点数多,搜索范围大,效率低.但能得到最优解. 如果估计的距离等于最短距离,那么搜索将严格沿着最短路径进行, 此时的搜索效率是最高的. 如果估计的距离大于最短

[Luogu P3953] 逛公园 (最短路+拓扑排序+DP)

题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易可以想到一个做法,就是魔改迪杰斯特拉做法: 如果一个点可以更新到达其他点的距离,那个点的方案数就是这个点的方案数:如果一个点所更新出来的距离和之前的相等,那个点的方案数加等当前点的方案数. 用式子可以表现为: f[j]=f[i] (dis[j]>dis[i]+x)   f[j]+=f[i] (dis

Luogu P3403 跳楼机|同余最短路

题意:给出跳楼机的4个操作,分别为 1.向上移动\(x\)层: 2.向上移动\(y\)层: 3.向上移动\(z\)层: 4.回到第一层. 显然,并不需要 求从第一层开始,能到达\(1\)到\(h\)中的多少层? \(1<=h<=2^{63}-1\) \(1<=x, y, z<=100000\) 题解: 好像可以直接\(DP\)? 布星啊,看下数据范围. 那先来推推定理? 接下来假设\(x\le y\le z\) 对于一个数\(k\),若它能到达,则\(k+x,k+2x,k+...\

luogu P1144 最短路计数

题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶点数与边数. 接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边. 输出格式: 输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可.如果无法到达顶点i则输出0. 输入输出样例 输入样例#1

【Luogu】P1144最短路计数(BFS)

题目链接 此题使用BFS记录最短路的条数.思路如下:因为是无权无向图,所以只要被BFS到就是最短路径.因此可以记录该点的最短路和最短路的条数:如果点y还没被访问过,则记录dis[y],同时令ans[y]=ans[x]. 如果点y已经被访问过且当前为最短路径,则ans[y]+=ans[x] #include<cstdio> #include<cctype> inline long long read(){ long long num=0,f=1; char ch=getchar();