[Sdoi2016]齿轮
4602: [Sdoi2016]齿轮
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 613 Solved: 324
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
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
Sample Output
Case #2: No
HINT
Source
//对于每组齿轮(u, v)连边,权值为y/x(反向边x/y)
//dfs 判断矛盾
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef double real;
inline void read(int &x){
register char ch=getchar();int f=1;x=0;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x*=f;
}
const int N=1e5+5;
const real eps=1e-6;
struct edge{int v,next;real w;}e[N<<1];int tot,head[N];
int T,n,m,cas;
bool vis[N],flag;
real val[N];
inline void add(int x,int y,real z){
e[++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
}
inline bool dfs(int x,real sp){
vis[x]=1;
val[x]=sp;
for(int i=head[x];i;i=e[i].next){
if(!vis[e[i].v]){
if(dfs(e[i].v,sp*e[i].w))
return 1;
}
else{
if(fabs(val[e[i].v]-sp*e[i].w)>eps)
return 1;
}
}
return 0;
}
inline void clr(){
tot=0;flag=0;
memset(head,0,(n+1)<<2);
memset(vis,0,(n+1)<<2);
}
int main(){
for(read(T);T--;clr()){
read(n);read(m);
for(int i=1,u,v,x,y;i<=m;i++){
read(u);read(v);
read(x),read(y);
add(u,v,(real)y/(real)x);
add(v,u,(real)x/(real)y);
}
for(int i=1;i<=n;i++) if(!vis[i]){
if(dfs(i,1)){
flag=1;break;
}
}
printf("Case #%d: %s\n",++cas,flag?"No":"Yes");
}
return 0;
}
首先可以看出这个齿轮的转动关系是具有传递性的,如果知道x和y的关系,也知道y和z的关系,就可以推出x和z的关系。具有这种关系的东西一般都可以用加权并查集来搞。对于每个元素给它维护一个dis[x],表示的含义是如果x的代表元素转动1圈,x要转动几圈。每次读入一个限制如果x和y不在同一个集合里就进行合并。合并的时候先找到x的代表元素r1和y的代表元素r2,然后我们要把r2合并到r1上。要进行合并就要知道r1转一圈的时候r2转几圈。设从读入的信息可以知道x转一圈的时候y转w圈,那么如果r1转了一圈,y就转了dis[x]∗w圈;而当y转了dis[x]∗w圈的时候,r2转了dis[x]∗w/dis[y]圈。关系如下图:
如果读入的x和y在一个集合里,那么就可以用维护的信息算出x转了一圈的时候y转了几圈,和读入的信息进行比对就可以判定是否发生矛盾。
这个数据范围看起来好像很小的样子。。但是如果它出上n-1个信息,每次都是当齿轮i转动1圈的时候齿轮i+1转动100圈,那么最后就会发现当齿轮1转动一圈的时候齿轮n会转动100n圈。。这样的话就不能直接用int或者long
long或者什么类似的东西来维护加权并查集的dis了。。用分解质因数似乎是比较稳的方法,但是听说用long double还是什么类似的东西也能过?
#include<cmath>
#include<cstdio>
using namespace std;
typedef double real;
inline void read(int &x){
register char ch=getchar();int f=1;x=0;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x*=f;
}
const int N=1e5+5;
const real eps=1e-6;
int T,n,m,cas;bool flag;
int fa[N];real dis[N];
int find(int x){
int t;
if(fa[x]!=x) t=find(fa[x]),dis[x]*=dis[fa[x]],fa[x]=t;
return fa[x];
}
int main(){
for(read(T);T--;flag=0){
read(n);read(m);
for(int i=1;i<=n;i++) fa[i]=i,dis[i]=1;
for(int i=1,r1,r2,u,v,x,y;i<=m;i++){
read(u);read(v);read(x);read(y);
r1=find(u);r2=find(v);
if(r1==r2){
if(fabs(dis[v]/dis[u]-(real)y/(real)x)>eps){
flag=1;break;
}
}
else{
fa[r2]=r1;
dis[r2]=(dis[u]*y)/(dis[v]*x);
}
}
printf("Case #%d: %s\n",++cas,flag?"No":"Yes");
}
return 0;
}
[Sdoi2016]齿轮的更多相关文章
- BZOJ 4602: [Sdoi2016]齿轮 dfs
4602: [Sdoi2016]齿轮 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4602 Description 现有一个传动系统,包 ...
- BZOJ4602 Sdoi2016 齿轮 【带权并查集】*
BZOJ4602 Sdoi2016 齿轮 Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组 ...
- bzoj 4602: [Sdoi2016]齿轮
4602: [Sdoi2016]齿轮 Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合 ...
- BZOJ4602:[SDOI2016]齿轮(并查集)
Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合齿轮,编号为u的齿轮转动x圈,编号为v ...
- 【bzoj4602】[Sdoi2016]齿轮 BFS
题目描述 给出一张n个点m条边的有向图,每条边 (u,v,x,y) 描述了 u 的点权乘 x 等于 v 的点权乘 y (点权可以为负).问:是否存在满足条件的图. 输入 有多组数据,第一行给定整数T, ...
- BZOJ4602 SDOI2016齿轮(搜索)
dfs一遍给每个齿轮随便标个值看是否矛盾就行了. #include<iostream> #include<cstdio> #include<cmath> #incl ...
- 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圈.传 ...
- NC20583 [SDOI2016]齿轮
题目链接 题目 题目描述 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y. 即如果只考虑这两个组合齿轮,编号为u的齿轮转动x圈,编号为 ...
随机推荐
- Hibernate的七种映射关系之七种关联映射(二)
继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.pri ...
- 038改变状态栏的颜色(扩展知识:关于iOS不同版本的消息通知知识)
效果如下: ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController @e ...
- 8 map的用法
what's map go里面的map和python字典差不多. 类似其他语言中的哈希表或者字典,以key-value的形式存储的数据 key必须是支持==或者!=比较运算的类型,不可以是函数.map ...
- 2 URL的玩法
preface 这里我主要说说flask的URL玩法 include: 动态URL规则 自定义URL转换器 HTTP方法 唯一的URL 构造URL 跳转和重定向 动态URL规则 URL规则可以添加变量 ...
- Unity判断网络是否连接以及判断是否连接WiFi
由于项目中的核心模块需要用到网络连接,所以需要首先检测用户是否有网络百度了下,有人说通过连接自己的服务器进行测试的,也有人说通过延迟来判断的最后发现原来Unity是提供了网络判断的方法的.Networ ...
- 让Json更懂中文(JSON_UNESCAPED_UNICODE)
我们知道, 用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式, 还会在一定程度上增加传输的数据量. <?php echo json_ ...
- 8 -- 深入使用Spring -- 1...两种后处理器
8.1 两种后处理器 Spring框架提供了很好的扩展性,出了可以与各种第三方框架良好整合外,其IoC容器也允许开发者进行扩展,这种扩展甚至无须实现BeanFactor或ApplicationCont ...
- 给树莓派安装看门狗的两种方法,二代B
树莓派的CPU是保护有硬件看门狗的,可以通过安装模块和值守程序来实现看门狗防止树莓派死机. 安装方法一:watchdog.sh的源码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- backbone学习笔记:视图(View)
Backbone 视图对象主要用来渲染数据,监听事件. Backbone的视图对象可以展示Model数据,也可以把用户编辑的Model数据传递到后台,可以通过监听事件操作视图里的DOM元素 举例: v ...
- 通过RF数据库查询中文字段结果正常显示的转换方法
方法1:统一显示为中文 1.通过RF数据库查询中文字段结果格式:'\xba\xcb\xbc\xf5\xcd\xa8\xb9\xfd' 2.通过Decode Bytes To String进行gbk解码 ...