\(\mathcal{Description}\)

  Link.

  给定一个 \(n\) 个点 \(m\) 条边的带权有向图,每条边还有属性 \(s\in\{-1,0,1\}\)。对于每个 \(u\in[1,n]\),求有多少个 \(x\in\mathbb Z\),使得图上所有属性为 \(-1\) 的边权 \(-x\),为 \(0\) 的不变,为 \(1\) 的 \(+x\) 后,从 \(1\) 走到 \(u\) 的任意路径不经过负环。若存在无穷个 \(x\),输出 \(-1\)。

  \(n\le100\),\(m\le10^4\)。

\(\mathcal{Solution}\)

  可以发现,对于任意初始权和为 \(b\) 的简单环,设其上 \(\sum_us_u=k\),则简单环的最终权值为 \(kx+b\),是一个一次函数,我们需要保证它非负。

  难免涉及到找负环,首先排除 SPFA,我们可以利用 Bellman-Ford 找负环:令 \(f(i,u)\) 表示从起点走 \(i\) 步到达 \(u\) 的最短路,若 \(f(n-1,u)\le f(n,u)\),则 \(u\) 和 \(u\) 可达的点都受负环影响。

  扩展到本题,我们需要记录 \(k\),那么令 \(f(i,u,k)\) 表示从起点走 \(i\) 步到达 \(u\),经过边的属性和为 \(k\) 的最短路,这个表可以暴力 \(\mathcal O(n^3m)\) 刷出来。对于一个确定的 \(x\),若 \(u\) 被负环影响,联系上面二维情况下的式子,就有:

\[\min_j\{f(n-1,u,j)+jx\}\le\min_k\{f(n,u,k)+kx\}
\]

  枚举 \(j,k\),若 \(j<k\),可以得到一个 \(x\) 的限制:

\[x\ge\frac{f(n-1,u,j)-f(n,u,k)}{k-j}
\]

  其余情况类似。这样对于每个结点,我们可以求出关于其的若干限制区间 \((l,r)\),表示合法的 \(x\not\in(l,r)\)。求答案时,枚举每个点 \(u\) 和其可达的点 \(v\),求 \(v\) 上限制的交集即可。

\(\mathcal{Code}\)

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm> typedef long long LL;
typedef std::pair<LL, LL> pll; inline char fgc () {
static char buf[1 << 17], *p = buf, *q = buf;
return p == q && ( q = buf + fread ( p = buf, 1, 1 << 17, stdin ), p == q ) ? EOF : *p ++;
} inline int rint () {
int x = 0, f = 1; char s = fgc ();
for ( ; s < '0' || '9' < s; s = fgc () ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = fgc () ) x = x * 10 + ( s ^ '0' );
return x * f;
} inline void wint ( LL x ) {
if ( x < 0 ) putchar ( '-' ), x = -x;
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} const int MAXN = 100, MAXM = 1e4;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int n, m;
LL pool[MAXN + 5][MAXN + 5][MAXN * 2 + 5];
bool rch[MAXN + 5][MAXN + 5];
std::vector<pll> restr[MAXN + 5], inter; struct Edge {
int u, v, w, s;
} eset[MAXM + 5]; inline void chkmin ( LL& a, const LL b ) { if ( b < a ) a = b; }
inline void chkmax ( LL& a, const LL b ) { if ( a < b ) a = b; } inline LL& f ( const int i, const int j, const int k ) { return pool[i][j][k + n + 2]; } int main () {
// freopen ( "city.in", "r", stdin );
// freopen ( "city.out", "w", stdout );
n = rint (), m = rint ();
for ( int i = 1; i <= n; ++ i ) rch[i][i] = true;
for ( int i = 1, u, v, w, s; i <= m; ++ i ) {
u = rint (), v = rint (), w = rint (), s = rint ();
eset[i].u = u, eset[i].v = v, eset[i].w = w, eset[i].s = s;
rch[u][v] = true;
}
for ( int k = 1; k <= n; ++ k ) {
for ( int i = 1; i <= n; ++ i ) {
for ( int j = 1; j <= n; ++ j ) {
rch[i][j] |= rch[i][k] && rch[k][j];
}
}
}
for ( int j = 1; j <= n; ++ j ) {
for ( int k = -n; k <= n; ++ k ) {
f ( 0, j, k ) = INF;
}
}
f ( 0, 1, 0 ) = 0;
for ( int i = 1; i <= n; ++ i ) {
for ( int j = 1; j <= n; ++ j ) {
for ( int k = -n; k <= n; ++ k ) {
f ( i, j, k ) = f ( i - 1, j, k );
}
}
for ( int j = 1; j <= m; ++ j ) {
int u = eset[j].u, v = eset[j].v, w = eset[j].w, s = eset[j].s;
for ( int k = -n; k <= n; ++ k ) {
if ( f ( i - 1, u, k ) == INF ) continue;
chkmin ( f ( i, v, k + s ), f ( i - 1, u, k ) + w );
}
}
}
for ( int i = 1; i <= n; ++ i ) {
for ( int k = -n; k <= n; ++ k ) {
if ( f ( n, i, k ) >= f ( n - 1, i, k ) ) continue;
LL l = -INF, r = INF; // x\in(-INF,l]+[r,INF).
for ( int j = -n; j <= n; ++ j ) {
if ( j == k || f ( n - 1, i, j ) == INF ) continue;
if ( j < k ) {
chkmin ( r, ceil ( 1.0 * ( f ( n - 1, i, j ) - f ( n, i, k ) ) / ( k - j ) ) );
} else {
chkmax ( l, floor ( 1.0 * ( f ( n - 1, i, j ) - f ( n, i, k ) ) / ( k - j ) ) );
}
}
if ( l < r ) restr[i].push_back ( pll ( l, r ) );
}
}
for ( int i = 1; i <= n; ++ i ) {
inter.clear ();
for ( int j = 1; j <= n; ++ j ) {
if ( rch[1][j] && rch[j][i] ) {
for ( int k = 0; k ^ restr[j].size (); ++ k ) {
inter.push_back ( restr[j][k] );
}
}
}
if ( inter.empty () ) { puts ( "-1" ); continue; }
std::sort ( inter.begin (), inter.end () );
LL l = INF, r = -INF, las = -INF; bool found = false;
for ( int j = 0; j ^ inter.size (); ++ j ) {
if ( !j && inter[j].first > -INF ) {
l = -INF, r = inter[j].first;
found = true; break;
}
if ( las != -INF && las <= inter[j].first ) {
l = las, r = inter[j].first;
found = true; break;
}
chkmax ( las, inter[j].second );
}
if ( !found && las < INF ) l = las, r = INF;
wint ( l == -INF || r == INF ? -1 : ( l <= r ? r - l + 1 : 0 ) );
putchar ( '\n' );
}
return 0;
}

\(\mathcal{Details}\)

  关于负环的做得太少,拿着就不知所措 qwq,而且考场上前面浪费太多时间根本没来得及向这题……

Solution -「UR #2」「UOJ #32」跳蚤公路的更多相关文章

  1. 「UR#5」怎样跑得更快

    「UR#5」怎样跑得更快 膜这个您就会了 下面是复读机mangoyang 我们要求 \[ \sum_{j=1}^n \gcd(i,j)^{c-d} j^d x_j=\frac{b_i}{i^d} \] ...

  2. 「UR#6」懒癌

    「UR#6」懒癌 妈妈我居然看了六个小时题解,快救救乌干达的可怜儿童吧. 接下来开始膜官方题解: ​ 其实就算有上面两个结论也不是很好想到任意复杂度的做法,关键在于要想到一个人是怎么推断自己的狗是不是 ...

  3. 「UR#5」怎样更有力气

    「UR#5」怎样更有力气 解题思路 考虑没有限制的情况,一定是把操作离线下来,按照边权从小到达做.可以发现,如果没有限制,完全图是多余的,直接拿树边进行合并就可以了.我们要做这么一件事情,把每个点属于 ...

  4. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  5. Android内存管理(4)*官方教程 含「高效内存的16条策略」 Managing Your App's Memory

    Managing Your App's Memory In this document How Android Manages Memory Sharing Memory Allocating and ...

  6. 「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp

    「bzoj1003」「ZJOI2006」物流运输---------------------------------------------------------------------------- ...

  7. 「bzoj1925」「Sdoi2010」地精部落 (计数型dp)

    「bzoj1925」「Sdoi2010」地精部落---------------------------------------------------------------------------- ...

  8. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  9. 【翻译】西川善司的「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,后篇

    http://www.4gamer.net/games/216/G021678/20140714079/     连载第2回的本回,  Arc System Works开发的格斗游戏「GUILTY G ...

随机推荐

  1. java 使用 ArrayList 排序【包括数字和字符串】

    1.数字排序 /** * 数字排序 */ @Test public void t2() { List<Integer> list = new ArrayList<>(); li ...

  2. 强化学习实战 | 自定义gym环境之显示字符串

    如果想用强化学习去实现扫雷.2048这种带有数字提示信息的游戏,自然是希望自定义 gym 环境时能把字符显示出来.上网查了很久,没有找到gym自带的图形工具Viewer可以显示字符串的信息,反而是通过 ...

  3. 几张图解释明白 Kubernetes Ingress

    来源:K8s技术圈 作者:阳明 Kubernetes Ingress 只是 Kubernetes 中的一个普通资源对象,需要一个对应的 Ingress 控制器来解析 Ingress 的规则,暴露服务到 ...

  4. Kotlin 协程一 —— 全面了解 Kotlin 协程

    一.协程的一些前置知识 1.1 进程和线程 1.1.1基本定义 1.1.2为什么要有线程 1.1.3 进程与线程的区别 1.2 协作式与抢占式 1.2.1 协作式 1.2.2 抢占式 1.3 协程 二 ...

  5. CentOS 7安装Odoo 15社区版的详细操作指南

    我之前的文章介绍过在Windows环境下安装Odoo 15,如果您需要在Windows部署,具体可参考我文末的微信号<10分钟教你本机电脑安装Odoo 15,并启用一个内置的项目APP应用> ...

  6. 【解决了一个小问题】golang go.mod中多了一个斜杠导致replace无效

    replace github.com/sxxx/common_lib/src/ => ../../common_lib/src 修改成 replace github.com/sxxx/commo ...

  7. Markdown最新使用说明

    Markdown基本语法说明 markdown 和 typora关系:typora是一款实时预览markdown的文本编辑器 本文推荐使用的Markdown编辑器为:Typora (用了多款编辑器,觉 ...

  8. golang中浮点型底层存储原理和decimal使用方法

    var price float32 = 39.29 float64和float32类似,只是用于表示各部分的位数不同而已,其中:sign=1位,exponent=11位,fraction=52位,也就 ...

  9. Servlet程序常见错误

    常见错误1:url-pattern中配置的路径没有以斜杠打头. 常见错误2:servlet-name配置的值不存在 常见错误3:servlet-class 标签的全类名配置错误

  10. ElasticSearch+Kibana+Packetbeat

    一.介绍 Packetbeat 是一个实时网络数据包分析工具,通过嗅探应用服务器之间的网络通讯,来解码应用层协议类型如HTTP.MySQL.redis等等,关联请求与响应,并记录每个事务有意义的字段. ...