首页 > 其他分享 > [USACO05DEC] Layout G 题解

[USACO05DEC] Layout G 题解

时间:2023-08-30 09:45:03浏览次数:42  
标签:Layout 1010100 int 题解 vis nex first USACO05DEC dis

fzqoj
luogu

题意

分别给出\(ml\)和\(md\)对,关于n头奶牛位置的关系,求1号到n号奶牛的最大距离是多少

每一对ml的关系转化成不等式就是: \(A - B \le C\)

相应的,每一对md的关系转化成不等式就是:\(A - B \geq C\) (\(A\),\(B\)是两头奶牛的位置,\(C\)是他们相差的距离)


思路

看到多元的不等式组,我们就可以考虑使用差分约束来求解此题

ml移项过后成了: \(A \le B + C\)

相当于是:\(B\)向\(A\)做了一条长度为\(C\)的边


md移项过后成了: \(B \le A - C\)

相当于是:\(A\)向\(B\)做了一条长度为\(-C\)的边


做法

因为此题有负边权,所以我们要用spfa来判环

-从一个源点开始求最短路,这条源点连向所有的边,保证图联通。如果有环的话,说明没有合法方案,直接输出\(-1\)

-接下来再从点1(也就是初始点)开始求最短路,如果最终的答案等于初始的极大值,说明他们之间的距离无穷远,直接输出\(-2\)

-最后,如果没有上面的问题,直接输出\(1\) - \(n\)的距离即可


\(Code\)

#include<bits/stdc++.h> 
using namespace std;

struct edge{
	int u, v, d, nex;
}g[1010100];
//存图

int n, ma, mb, a, b, c, dis[1010100] = {0}, first[1010100] = {0}, cnt = 0, vis[1010100] = {0}, du[1010100] = {0};

void update(int u, int v, int d){
	g[++cnt] = (edge){u, v, d, first[u]}, first[u] = cnt;
}
//建图

int spfa(int f){
	for(int i = 0; i <= n; i++) du[i] = 0, vis[i] = 0;
	memset(dis, 0x3f, sizeof(dis));//初始值赋极大值
	queue<int>p;
	p.push(f), vis[f] = 1, dis[f] = 0;
	while(!p.empty()){
		int nex = p.front();
		p.pop(), vis[nex] = 0;
		for(int i = first[nex]; i; i = g[i].nex){
			if(dis[nex] + g[i].d < dis[g[i].v]){
				dis[g[i].v] = dis[nex] + g[i].d;
				if(!vis[g[i].v]){
					vis[g[i].v] = 1, p.push(g[i].v), du[g[i].v]++;
					if(du[g[i].v] > n) return -1;//判断是否存在负权环
				}
			}
		}
	}
	return dis[n] == 0x3f3f3f3f ? -2 : dis[n];//如果没有更新这个点,输出-2
}

int main(){
	scanf("%d %d %d", &n, &ma, &mb);
	while(ma--){
		scanf("%d %d %d", &a, &b, &c);
		update(a, b, c);
	}
	while(mb--){
		scanf("%d %d %d", &a, &b, &c);
		update(b, a, -c);
	}
    //根据前面推出来的式子建图
	for(int i = 1; i <= n; i++) update(0, i, 0);//源点连接每一个点,防止图不联通
	if(spfa(0) == -1) printf("-1");//如果有负权环,输出-1
	else printf("%d", spfa(1));
	return 0;
}

QAQ

标签:Layout,1010100,int,题解,vis,nex,first,USACO05DEC,dis
From: https://www.cnblogs.com/koukilee/p/17666435.html

相关文章

  • CF1864D Matrix Cascade 题解
    首先把式子拆一下,可以知道\(x-i\ge|y-j|\)等价于\(x-y\gei-j\)和\(x+y\gei+j\),注意到每次操作\((i,j)\),影响到的点\((x,y)\)均要满足\(x>i\),那么我们每次就必须要按照从上往下的顺序进行,否则上面的点无法影响到,即从第一行开始操作。又注意到对于\((i,j)\)如果执......
  • CF1864B Swap and Reverse 题解
    注意到交换操作,无法改变下标的奇偶性,因此只能通过考虑翻转操作改变。注意到如果\(i\)是奇数,那么要令\(i+k-1\)为偶数的话\(k\)必须为偶数,若\(i\)是偶数,要令\(i+k-1\)是奇数的话,\(k\)也应为偶数,而\(k\)为奇数的情况翻转了也无法改变奇偶性。因此通过\(k\)的奇偶性......
  • CF1839C Insert Zero and Invert Prefix 题解
    首先考虑无解的情况,很明显\(a_n\)必须为\(0\),否则没有解,因为如果最后一位为\(1\)那么必须有\(n\)这个数存在于\(b\)序列中,而这种情况时不符合题意的。然后考虑如何求解,先考虑一种比较特殊的情况,就是若干个\(1\)后面接着一个\(0\),这里假设\(1\)的数量有\(k\)个,这......
  • P9437 『XYGOI round1』一棵树 题解
    首先这是一道很明显的换根dp。首先注意到要拼接数,所以我们可以先处理出\(num_i=10^{x}\),使得\(10^x>a_i>10^{x-1}\),这样方便我们后面算贡献。我们以这棵树为例子来推状态转移方程。先假设\(dp_u\)表示以\(1\)为根时,从\(u\)的子树的点到\(u\)的权值和。那么\[......
  • CF1862E Kolya and Movie Theatre 题解
    先注意到我们娱乐值损耗的多少只与最后一场电影有关系,所以假设最后一场电影看的下标为\(k\),那么最后就要减去\(d\timesk\)。得出这个性质之后开个小根堆反悔贪心即可,首先\(a_i<0\)的没必要考虑,对于\(a_i>0\)的,如果还没到\(m\)场电影,我们就直接往里塞就可以,如果到了,我们......
  • P8675 [蓝桥杯 2018 国 B] 搭积木 题解
    总述此题用区间dp解决,二维前缀和优化。朴素做法阶段:自上而下数每一层。状态:\(dp_{i,l,r}\)表示自上而下数第\(i\)行中在\([l,r]\)摆积木的方案数。状态转移方程:根据题意可知,若要在\([l,r]\)中摆积木,那么\([l,r]\)中不允许有\(\tt{X}\),而第\(i\)层的\([l,r]\)......
  • P7809 [JRKSJ R2] 01 序列 题解
    对于第二种操作,很容易想到只有\(1\)或\(2\)两种答案,若该区间内存在\(01\)这个子序列,那么答案为\(2\)反之为\(1\).可以通过对该\(01\)串做一个前缀和,若出现\(01\)这个子序列就累加,最后判断左右端点是否相等即可,时间复杂度\(O(n)\).对于第一种操作,\(\text{Subtest1}......
  • CF1833D Flipper 题解
    赛场上思路出来了但是代码没调出来。首先考虑右端点,很明显,要让操作后的序列字典序尽量地大,那么就要使操作后的序列第一个数尽量地大,考虑\(n\)或\(n-1\),如果\(n\)在原序列的第一个位置,那么此时无论怎么调整都无法使得它在新序列的第一个位置,此时就要考虑让\(n-1\)在新序列......
  • UVA10054 The Necklace题解
    题意给定一个无向图,其中至多有\(50\)个结点,求是否有欧拉回路。题解很明显就是一个无向图求欧拉回路的板子,我们用\(\tt{Hierholzer}\),先说存图,要明确的一个点是这个无向图里是有可能有重边的,所以我们要注意记录的时候不应是单独地记录某一条边是否存在,而是要记录某一条边的数......
  • UVA967的题解
    设\(check_i\)为\(1\simn\)中满足题意的数的数量。显然答案为\(check_j-check_{i-1}\)。注意到\(check\)能直接暴力求出来。那么就可以先把\(10^6\)范围内的所有质数求出来,然后所有数跑一遍,每个数都去旋转得出所有数后判断是否均为质数,记录下来。代码很好写。#incl......