【bzoj4602】[Sdoi2016]齿轮 BFS
题目描述
给出一张n个点m条边的有向图,每条边 (u,v,x,y) 描述了 u 的点权乘 x 等于 v 的点权乘 y (点权可以为负)。问:是否存在满足条件的图。
输入
输出
样例输入
2
3 3
1 2 3 5
2 3 5 -7
1 3 3 -7
3 3
1 2 3 5
2 3 5 -7
1 3 3 7
样例输出
Case #1: Yes
Case #2: No
题解
BFS
显然固定一个点,通过条件判断出其它点是否是它的固定倍数即可。添加双向边,维护每个点是某个点的多少倍,BFS验证。
但是有一个问题:倍数关系是指数级的,因此需要取对数。
但是有一个问题:边权有负数,因此需要维护符号和绝对值的对数。
但是有一个问题:有精度误差,因此需要设eps为$10^{-6}$。
时间复杂度$O(T(n+m))$
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#define N 1010
#define M 20010
using namespace std;
queue<int> q;
int head[N] , to[M] , vp[M] , next[M] , cnt , vis[N] , flag[N];
double val[M] , dis[N];
void add(int x , int y , double z , int p)
{
to[++cnt] = y , val[cnt] = z , vp[cnt] = p , next[cnt] = head[x] , head[x] = cnt;
}
bool judge(int p)
{
int i , x;
while(!q.empty()) q.pop();
vis[p] = 1 , q.push(p);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(!vis[to[i]]) vis[to[i]] = 1 , flag[to[i]] = flag[x] ^ vp[i] , dis[to[i]] = dis[x] + val[i] , q.push(to[i]);
else if(flag[to[i]] != (flag[x] ^ vp[i]) || fabs(dis[to[i]] - dis[x] - val[i]) > 1e-6) return 0;
}
}
return 1;
}
int main()
{
int T , Case;
scanf("%d" , &T);
for(Case = 1 ; Case <= T ; Case ++ )
{
memset(head , 0 , sizeof(head)) , memset(vis , 0 , sizeof(vis)) , cnt = 0;
int n , m , x , y , i , a , b;
scanf("%d%d" , &n , &m);
while(m -- )
{
scanf("%d%d%d%d" , &x , &y , &a , &b);
if(b > 0) add(x , y , log(b) - log(a) , 0) , add(y , x , log(a) - log(b) , 0);
else add(x , y , log(-b) - log(a) , 1) , add(y , x , log(a) - log(-b) , 1);
}
for(i = 1 ; i <= n ; i ++ )
if(!vis[i])
if(!judge(i))
break;
printf("Case #%d: " , Case);
if(i > n) puts("Yes");
else puts("No");
}
return 0;
}
【bzoj4602】[Sdoi2016]齿轮 BFS的更多相关文章
- BZOJ4602 Sdoi2016 齿轮 【带权并查集】*
BZOJ4602 Sdoi2016 齿轮 Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组 ...
- BZOJ4602 SDOI2016齿轮(搜索)
dfs一遍给每个齿轮随便标个值看是否矛盾就行了. #include<iostream> #include<cstdio> #include<cmath> #incl ...
- BZOJ4602:[SDOI2016]齿轮(并查集)
Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合齿轮,编号为u的齿轮转动x圈,编号为v ...
- bzoj4602 [Sdoi2016]齿轮
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4602 [题解] 对于每组齿轮(u, v)连边,权值为y/x(反向边x/y) 那么直接dfs计 ...
- [bzoj4602][Sdoi2016]齿轮——dfs
题目 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合齿轮,编号为u的齿轮转动x圈,编号为v的齿轮会转动y圈.传 ...
- BZOJ4602: [Sdoi2016]齿轮(并查集 启发式合并)
题意 题目链接 Sol 和cc的一道题很像啊 对于初始的\(N\)个点,每加一条限制实际上就是合并了两个联通块. 那么我们预处理出\(val[i]\)表示的是\(i\)节点所在的联通块根节点转了\(1 ...
- BZOJ4602: [Sdoi2016]齿轮 DFS 逆元
这道题就是一个DFS,有一篇奶牛题几乎一样.但是这道题卡精度. 这道题网上的另一篇题解是有问题的.取对数这种方法可以被轻松卡.比如1e18 与 (1e9-1)*(1e9+1)取对数根本无法保证不被卡精 ...
- [Sdoi2016]齿轮
4602: [Sdoi2016]齿轮 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 613 Solved: 324 [Submit][Status ...
- BZOJ 4602: [Sdoi2016]齿轮 dfs
4602: [Sdoi2016]齿轮 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4602 Description 现有一个传动系统,包 ...
随机推荐
- ld: i386 架构于输入文件 bar.o 与 i386:x86-64 输出不兼容
报错:ld: i386 架构于输入文件 foo.o 与 i386:x86-64 输出不兼容 或者:ld: i386 architecture of input file `foo.o' is inco ...
- 【转】odoo学习之:Environment
Environment类提供了对ORM对象的封装,同时提供了对注册类的访问,记录集的缓存,以及管理重计算的数据结构. 对于继承了Model的类来说可以直接通过self.env对Environment进 ...
- 北京Uber优步司机奖励政策(1月19日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 成都Uber优步司机奖励政策(1月12日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 成都Uber优步司机奖励政策(8月31日~9月6日)
本周(8月31日-9月6日),优步成都继续推出丰厚保底奖励,日保底总金额最高575元,每周保底最高可获得3595元.优步还加大了乘客端折扣力度,最低五折坐车!单子超多,上线就有单,接单接不停!欢迎各位 ...
- cakephp1.3中help form的一个小问题
如果我们在模版里这么干 <?php echo $form->input('last_sold_date',array('autocomplete'=>'off','label'=&g ...
- ruby 基础教程1-8-1
1.":class, instance_of?, :is_a?"都是Object类的方法,每个对象都可以调用 2.":class"方法用户获取对象归属类的名称 ...
- 使用union 外加count
explain extended and name='aaa')) t; +----+--------------+------------+-------+---------------+----- ...
- 「日常训练」Kefa and Dishes(Codeforces Round #321 Div. 2 D)
题意与分析(CodeForces 580D) 一个人有\(n\)道菜,然后要点\(m\)道菜,每道菜有一个美味程度:然后给你了很多个关系,表示如果\(x\)刚好在\(y\)前面做的话,他的美味程度就会 ...
- 「日常训练」Case of Matryoshkas(Codeforces Round #310 Div. 2 C)
题意与分析(CodeForces 556C) 为了将所有\(n\)个娃娃编号递增地串在一起(原先是若干个串,每个串是递增的), 我们有两种操作: 拆出当前串中最大编号的娃娃(且一定是最右边的娃娃). ...