洛谷 P5590 赛车游戏

P5590 赛车游戏

Problem

给一张有向图,请给每一条边赋上边权\(w\in[1,9]\)使得每一条\(1\to n\)的路径的长度相等。

Solution

先来点前置知识:差分约束。

简述

将很多对变量之间的差\(\le c\)的关系转化为图论,再用图论算法来求解这个不等式组的解。

步骤

对于\(x_j-x_i\le k\),我们会发现它类似最短路网络中的三角不等式\(d_v-d_u\le w_{<u,v>}\).我们将每一个变量看作一个点,再建立一个超级原点\(x_0\)并向每一个点连一条权值为0的有向边。对于每一个不等式\(x-y\le k\to x\le y+k\),我们连一条由\(y\)指向\(x\),权值为\(k\)的有向边,然后跑最短路。

在建图的过程中要先关注具体问题,若求的是两个变量差的最大值,那么将所有不等式转变成"<="的形式并且在建图后求最短路,反之在转换成">="的形式,并且求最长路

另外,如果有负环,那么该不等式组无解。我们只要放心大胆的跑SPFA就好。如果一个点入队次数大于\(n\),说明存在负环。

Code

见模板题


好。接下来回到这道题。

给一张有向图,请给每一条边赋上边权\(w\in[1,9]\)使得每一条\(1\to n\)的路径的长度相等。

如果始终想的是如何让所有\(1\to n\)的路径相等那么就想错方向了。

在一个图中进行最短路的时候,\(dis_x+w_{x\to v}=dis_v\)说明\(dis_v-dis_x=w_{x\to v}\in[1,9]\),这样我们才可以用差分约束系统进行求解。

\(1\le dis_v-dis_x\le9\longrightarrow dis_v\le dis_x+9\bigvee dis_x\le dis_v-1\),所以我们连一条\(x\to v\)权值为9的边,一条\(v\to x\)权值为\(-1\)的边。

Code

/**************************************************************
* Problem: 5590
* Author: Vanilla_chan
* Date: 20210330
* E-Mail: Vanilla_chan@outlook.com
**************************************************************/
//预编译部分已略
#define N 2010
#define M 8000
int head[N],ver[M],nxt[M],w[M];
int cnt;
void insert(int x,int y,int z)
{
nxt[++cnt]=head[x];
head[x]=cnt;
ver[cnt]=y;
w[cnt]=z;
}
int f[N];
int getf(int x)
{
if(f[x]==x) return x;
return f[x]=getf(f[x]);
} void merge(int x,int y)
{
x=getf(x);
y=getf(y);
if(x==y) return;
f[x]=y;
} int n,m;
vector<int>edge[N],redge[N];
int u[N],v[N];
int useful[N];
bool book[N];
void dfs(int x)
{
if(book[x]) return;
book[x]=1;
useful[x]++;
for(unsigned int i=0,v;i<edge[x].size();i++)
{
v=edge[x][i];
dfs(v);
}
}
void rdfs(int x)
{
if(book[x]) return;
book[x]=1;
useful[x]++;
for(unsigned int i=0,v;i<redge[x].size();i++)
{
v=redge[x][i];
rdfs(v);
}
}
queue<int>q;
int dis[N];
int tot[N];
bool SPFA(int x)
{
while(q.size()) q.pop();
memset(dis,0x3f,sizeof(dis));
dis[x]=0;
memset(book,0,sizeof(book));
book[x]=1;
q.push(x);
while(q.size())
{
x=q.front();
q.pop();
book[x]=0;
for(int i=head[x],v;i;i=nxt[i])
{
v=ver[i];
if(dis[v]>dis[x]+w[i])
{
dis[v]=dis[x]+w[i];
if(!book[v])
{
tot[v]++;
if(tot[v]>n) return 0;
book[v]=1;
q.push(v);
}
}
}
}
return 1;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read();
m=read();
for(int i=1;i<=m;i++)
{
u[i]=read();
v[i]=read();
edge[u[i]].push_back(v[i]);
redge[v[i]].push_back(u[i]);
merge(u[i],v[i]);
}
if(getf(1)!=getf(n))
{
cout<<"-1"<<endl;
return 0;
}
for(int i=1;i<=n;i++) useful[i]=-1;
dfs(1);
memset(book,0,sizeof(book));
rdfs(n);
memset(book,0,sizeof(book));
for(int i=1;i<=n;i++)
{
if(useful[i]!=1) useful[i]=0;
}
if(useful[1]==0||useful[n]==0)
{
cout<<"-1"<<endl;
return 0;
}
for(int i=1;i<=m;i++)
{
if(useful[u[i]]&&useful[v[i]])
{
insert(u[i],v[i],9);
insert(v[i],u[i],-1);
}
}
if(SPFA(1)==0)
{
cout<<"-1"<<endl;
return 0;
}
cout<<n<<" "<<m<<endl;
for(int i=1;i<=m;i++)
{
cout<<u[i]<<" "<<v[i]<<" ";
if(useful[u[i]]&&useful[v[i]])
{
cout<<dis[v[i]]-dis[u[i]];
}
else cout<<rand()%9+1;
cout<<endl;
}
return 0;
}

洛谷 P5590 赛车游戏的更多相关文章

  1. 洛谷 P2197 nim游戏

    洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...

  2. 洛谷 P1965 转圈游戏

    洛谷 P1965 转圈游戏 传送门 思路 每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,--,依此类推,第n − m号位置上的小伙伴走到第 0 号 ...

  3. 洛谷 P1000 超级玛丽游戏

    P1000 超级玛丽游戏 题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 题目描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级 ...

  4. 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山

    前提说明,因为我比较菜,关于理论性的证明大部分是搬来其他大佬的,相应地方有注明. 我自己写的部分换颜色来便于区分. 邻项交换对比是求一定条件下的最优排序的思想(个人理解).这部分最近做了一些题,就一起 ...

  5. $loj10156/$洛谷$2016$ 战略游戏 树形$DP$

    洛谷loj Desription Bob 喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的方法.现在他有个问题. 现在他有座古城堡,古城堡的路形成一棵树.他要在这棵树的节点上放置最少数 ...

  6. 洛谷P1000 超级玛丽游戏(洛谷新手村1-1-1)

    题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 题目描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级玛丽中的一个场景. *** ...

  7. 洛谷P1080 国王游戏 python解法 - 高精 贪心 排序

    洛谷的题目实在是裹脚布 还编的像童话 这题要 "使得获得奖赏最多的大臣,所获奖赏尽可能的少." 看了半天都觉得不像人话 总算理解后 简单说题目的意思就是 根据既定的运算规则 如何排 ...

  8. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  9. 洛谷3825 [NOI2017]游戏 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...

  10. 【题解】洛谷P1070 道路游戏(线性DP)

    次元传送门:洛谷P1070 思路 一开始以为要用什么玄学优化 没想到O3就可以过了 我们只需要设f[i]为到时间i时的最多金币 需要倒着推回去 即当前值可以从某个点来 那么状态转移方程为: f[i]= ...

随机推荐

  1. kali安装pdtm工具

    kali安装pdtm工具 前言 今天想安装一下pdtm工具集的,但过程中一直出现各种错误,找了几篇文章之后并没有找到解决方法,后解决之后写了这样一篇文章希望可以解决大家在安装过程中碰到的部分问题 介绍 ...

  2. 解决 Mac(M1/M2)芯片,使用node 14版本

    前言 nvm 在安装 Node.js v14.21.3 时,报错: nvm install 14 Downloading and installing node v14.21.3... Downloa ...

  3. js 时间转时间戳

    前言 有时候我们用时间插件,选择好时间后,需要把日期格式转化为时间戳,再传到后台 时间转时间戳 let time = Math.floor(new Date("2014-04-23 18:5 ...

  4. 在 Go 中恰到好处的内存对齐

    问题 type Part1 struct { a bool b int32 c int8 d int64 e byte } 在开始之前,希望你计算一下 Part1 共占用的大小是多少呢? func m ...

  5. 什么是单点登录?什么是SSO?什么是CAS?

    目录 单点登录简介 SSO&CAS是什么 单点登录适合什么场景 单点登录的三种实现方式 CAS的几个重要知识点 CAS的实现过程 单点登录简介 单点登录(SingleSignOn,SSO),就 ...

  6. Sql语句:数据操作

    数据操作,核心是:增删改查. 其中查与增删改不同,要返回数据集,其他的只要知道是否修改成功即可,所以一般调用时,返回值不同,这点要注意. 一.查询: select sname,sdept,sage f ...

  7. 阿里云ECS服务器Ubuntu下安装docker-ce技巧

    官方文档 先来份Ubuntu 下安装 docker 的官方文档 -> Get Docker CE for Ubuntu 官方文档的安装方式是最靠谱的,但是对于国内的小伙伴来说墙是硬伤... 国内 ...

  8. 二叉树 (王道数据结构 C语言版)

    2004.11.04 计算一颗给定二叉树的所有双分支节点个数 编写把一个树的所有左右子树进行交换的函数 求先序遍历中第k个结点的值 (1 <= k <= 二叉树中的结点个数) #inclu ...

  9. jmeter从文档CSV内读取参数且文件路径为相对路径

    如下图,"全站链接扫描"脚本的参数化文件存储在同一目录的参数化文件夹内 预计实现读取该文件使用相对路径(非绝对路径,避免脚本在另一台电脑存在别的目录下能正常读取参数文件) 如读取& ...

  10. fiddler抓包常用辅助工具

    一.过滤器 1.hosts: 只展示内网或外网的hosts,internet(外网),Intranet(内网) 展示下面的hosts/隐藏下面的hosts/:选择后填写需要设置的hosts(地址前面的 ...