【bzoj4602】【SDOI2016】【齿轮】【dfs】
来源:互联网 发布:淘宝客佣金代扣 编辑:程序博客网 时间:2024/06/09 18:52
Description
现有一个传动系统,包含了N个组合齿轮和M个链条。每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x
: y。即如果只考虑这两个组合齿轮,编号为u的齿轮转动x圈,编号为v的齿轮会转动y圈。传动比为正表示若编号
为u的齿轮顺时针转动,则编号为v的齿轮也顺时针转动。传动比为负表示若编号为u的齿轮顺时针转动,则编号为v
的齿轮会逆时针转动。若不同链条的传动比不相容,则有些齿轮无法转动。我们希望知道,系统中的这N个组合齿
轮能否同时转动。
Input
有多组数据,第一行给定整数T,表示总的数据组数,之后依次给出T组数据。每一组数据的第一行给定整数N和
M,表示齿轮总数和链条总数。之后有M行,依次描述了每一个链条,其中每一行给定四个整数u,v,x和y,表示
只考虑这一组联动关系的情况下,编号为u的齿轮转动x圈,编号为v的齿轮会转动y圈。请注意,x为正整数,而y为
非零整数,但是y有可能为负数。
T<=32,N<=1000,M<=10000且x与y的绝对值均不超过100
Output
输出T行,对应每一组数据。首先应该输出标识这是第几组数据,参见样例输出。之后输出判定结果,如果N个组合
齿轮可以同时正常运行,则输出Yes,否则输出No。
Sample Input
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
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 #1: Yes
Case #2: No
题解:
直接dfs精度会爆(不过貌似数据并没有爆);
可以把所有数分解质因数,处理出从一个齿轮到它连着的齿轮每个质因子变化了多少.
对于每个质因子都dfs一遍.
最后再dfs一遍正负即可.
代码:
#include<iostream>#include<cstdio>#include<cstring>#define N 1010#define M 10010using namespace std;int point[N],T,next[M<<1],n,m,cnt,t,prime[110],num,f[N],vis[N];struct use{ int x,y,a,b;}p[M];struct edge{ int st,en,v;}e[M<<1];int read(){ int f(1),x(0); char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}void pre(){ for (int i=2;i<=100;i++){ if (!f[i]) prime[++num]=i; for (int j=1;j<=num&&i*prime[j]<=100;j++){ f[i*prime[j]]=1; if (i%prime[j]==0) break; } }}void add(int x,int y,int v){ next[++cnt]=point[x];point[x]=cnt; e[cnt].en=y;e[cnt].v=v;}bool dfs1(int x){ for (int i=point[x];i;i=next[i]) if (vis[e[i].en]==vis[0]){ vis[e[i].en]=vis[x]+e[i].v; if (!dfs1(e[i].en)) return 0; } else{ if (vis[e[i].en]!=vis[x]+e[i].v) return 0; } return 1;}bool dfs2(int x){ for (int i=point[x];i;i=next[i]) if (vis[e[i].en]==vis[0]){ vis[e[i].en]=vis[x]^e[i].v; if (!dfs2(e[i].en)) return 0; } else{ if (vis[e[i].en]!=vis[x]^e[i].v) return 0; } return 1;}bool cal(){ for (int i=1;i<=num;i++){ memset(point,0,sizeof(point));cnt=0; for (int j=1;j<=m;j++){ int a=p[j].a,b=p[j].b,t(0); while (a%prime[i]==0){a/=prime[i];t++;} while (b%prime[i]==0){b/=prime[i];t--;} add(p[j].x,p[j].y,t); add(p[j].y,p[j].x,-t); } memset(vis,127/3,sizeof(vis)); for (int j=1;j<=n;j++) if (vis[j]==vis[0]){ vis[j]=0; if (!dfs1(j)) return 0; } } memset(point,0,sizeof(point));cnt=0; for (int j=1;j<=m;j++){ int a=p[j].a,b=p[j].b,c=0; if (a>0&&b<0||a<0&&b>0) c=1; add(p[j].x,p[j].y,c); add(p[j].y,p[j].x,c); } memset(vis,127/3,sizeof(vis)); for (int j=1;j<=n;j++) if (vis[j]==vis[0]){ vis[j]=0; if (!dfs2(j)) return 0; } return 1;}void init(){ n=read();m=read(); for (int i=1;i<=m;i++){ p[i].x=read();p[i].y=read();p[i].a=read();p[i].b=read(); }}int main(){ T=read();pre();t=0; while (T--){ init();t++; printf("Case #%d: ",t); if (cal()) puts("Yes"); else puts("No"); }}
0 0
- 【bzoj4602】【SDOI2016】【齿轮】【dfs】
- 【bzoj4602】[Sdoi2016]齿轮 dfs
- BZOJ4602 [Sdoi2016]齿轮
- BZOJ4602: [Sdoi2016]齿轮
- bzoj4602 [Sdoi2016]齿轮
- bzoj4602: [Sdoi2016]齿轮
- [SDOI2016] BZOJ4602 齿轮-dfs-带权并查集-数论逆元-质因数分解
- [BZOJ4602][Sdoi2016]齿轮(加权并查集+分解质因数)
- [BZOJ4602][Sdoi2016]齿轮(加权并查集)
- [dfs] BZOJ 4602 [Sdoi2016]齿轮
- bzoj 4602: [Sdoi2016]齿轮
- BZOJ 4602 [Sdoi2016]齿轮
- 4602: [Sdoi2016]齿轮
- 【BZOJ4602】齿轮,带权并查集
- bzoj 4602: [Sdoi2016]齿轮(加权并查集)
- BZOJ[4602] [Sdoi2016]齿轮 加权并查集
- 数齿轮
- 齿轮基础
- SQL Serve2008的一些操作
- echarts图表点击事件之跳转页面和加载页面
- Android Studio 使用NDK
- js判断浏览器类型
- Android应用签名详解
- 【bzoj4602】【SDOI2016】【齿轮】【dfs】
- C++作业6
- 【学习C++】C++ Primer Plus (第六版)第十一章编程练习1-7
- vtkPropPicker在图像处理中的应用
- 设计模式 - Prototype 模式
- jar签名(同目录下的所有jar包,并导出签名文件).bat
- Childhood Game 取石子
- Android快速实现热更新
- asp.net 验证控件结合正则表达式验证