4602: [Sdoi2016]齿轮

Posted lwq12138

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4602: [Sdoi2016]齿轮相关的知识,希望对你有一定的参考价值。

4602: [Sdoi2016]齿轮

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

Sample Output

Case #1: Yes
Case #2: No
题解:
dfs,按要求连边,边权即为比值,然后直接赋值搜索,遇到矛盾时退出。。
但是这题还有精度问题,随便搞一下就好了。。
#include<stdio.h>
#include<iostream>
using namespace std;
const int N=1005;
const int M=10005;
#define eps 1e-8
int T,n,m,i,x,y,u,v,ok,Case,p[N];
int tot,head[N],Next[M<<1],to[M<<1];
double a[M<<1],f[N];
void add(int u,int v,double x)
{
    tot++;
    to[tot]=v;
    a[tot]=x;
    Next[tot]=head[u];
    head[u]=tot;
}
bool dfs(int x)
{
    int i;
    p[x]=1;
    for(i=head[x];i!=-1;i=Next[i])
    {
        int y=to[i];
        if(p[y]==0)
        {
            f[y]=f[x]*a[i];
            if(dfs(y)==0) return 0;
        } else
        if((f[x]*a[i]-f[y])>eps) return 0;
    }
    return 1;
}
int main()
{
    scanf("%d",&T);
    Case=0;
    while(T--)
    {
        scanf("%d%d",&n,&m);
        tot=0;
        for(i=1;i<=n;i++)
            head[i]=-1,p[i]=0,f[i]=0;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&u,&v,&x,&y);
            add(u,v,1.0*x/y);
            add(v,u,1.0*y/x);
        }
        ok=0;
        for(i=1;i<=n;i++)
            if(p[i]==0)
        {
            f[i]=1.0;
            if(dfs(i)==0)
            {
                ok=1;
                break;
            }
        }
        Case++;
        printf("Case #%d: ",Case);
        if(ok==0) printf("Yes\n");else printf("No\n");
    }
    return 0;
}

 

 

以上是关于4602: [Sdoi2016]齿轮的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj4602] [Sdoi2016]齿轮

Bzoj4602--Sdoi2016齿轮

bzoj 4602: [Sdoi2016]齿轮

BZOJ4602: [Sdoi2016]齿轮 DFS 逆元

bzoj 4602: [Sdoi2016]齿轮

[Sdoi2016]齿轮