BZOJ 4602 [Sdoi2016]齿轮

来源:互联网 发布:自动复制粘贴软件 编辑:程序博客网 时间:2024/04/29 19:47

爆搜+取对数优化

很显然我们可以定一个点,然后DFS下去看有没有矛盾。但是这样会炸精度。于是考虑判断a*b==a*c可以转为判断log(a*b)==log(a*c)也就是log(a)+log(b)==log(a)+log(c)。这样精度就安全了。

#include<cstdio>#include<cmath>#include<cstring>#define N 1005#define M 10005using namespace std;struct edge{int next,to;double v;bool cir;}e[M<<1];const double eps = 1e-8;double f[N];int last[N], ecnt;bool flag, vis[N], cir[N];void add(int a, int b, double v, bool c){    e[++ecnt]=(edge){last[a],b,v,c};    last[a]=ecnt;}void clear(){    ecnt=0;    memset(last,0,sizeof(last));    memset(vis,0,sizeof(vis));}void dfs(int x, double sum, bool c){    vis[x]=1; f[x]=sum; cir[x]=c;    for(int i = last[x]; i; i=e[i].next)    {        int y=e[i].to;        if(vis[y])        {            if(cir[y]!=(c^e[i].cir) || abs(sum+e[i].v-f[y])>eps)            {                flag=0;                return;            }        }        else        {            dfs(y,sum+e[i].v,c^e[i].cir);            if(!flag)return;        }    }}int main(){    int T;    scanf("%d",&T);    for(int t = 1; t <= T; t++)    {        clear();        int n, m;        scanf("%d%d",&n,&m);        for(int i = 1; i <= m; i++)        {            int u, v; double x, y;            scanf("%d%d%lf%lf",&u,&v,&x,&y);            add(u,v,log(abs(y/x)),y<0);            add(v,u,log(abs(x/y)),y<0);        }        flag=1;        for(int i = 1; i <= n && flag; i++)            if(!vis[i])                dfs(i,0,0);        if(flag)printf("Case #%d: Yes\n",t);        else printf("Case #%d: No\n",t);    }}
0 0
原创粉丝点击