bzoj 4602: [Sdoi2016]齿轮

传送门

题解:

一个简单的dfs或并查集即可搞定。

dfs做法:建出图来以后,由一个节点跑一遍,如果儿子节点没有被遍历过,dfs此节点,否则,判断他俩的比例与他俩到根节点的比例之比是否相等。

对于判断两节点的比例,double可以安全存下。

我怕炸精度(其实不会,感觉自己跟个zz一样),于是想不用double,用个pair存下分子分母。后来觉得导起来太麻烦,于是用逆元求(越来越傻了)。

逆元不需要太大的素数,大了会T,小了会WA。

bzoj上测试了6个素数:1000000007,66191,7307,233,151,103.测试结果如下。

附上代码:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 #define ll long long
 9 struct tree{
10     int u,v,next;
11     ll d;
12 }l[20100];
13 ll mod=151,dis[1010];
14 int lian[20100],n,m,t,e;
15 bool pd[1010],cuo;
16 ll ksm(ll,ll);
17 void bian(int,int,ll);
18 void dfs(int,int);
19 int main()
20 {
21 //    freopen("in.txt","r",stdin);
22     scanf("%d",&t);
23     for(int jjj=1;jjj<=t;jjj++)
24     {
25         memset(dis,0,sizeof(dis));
26         memset(lian,0,sizeof(lian));
27         memset(pd,0,sizeof(pd));
28         e=0;cuo=0;
29         scanf("%d%d",&n,&m);
30         for(int i=1;i<=m;i++)
31         {
32             int x,y,u,v;
33             scanf("%d%d%d%d",&x,&y,&u,&v);
34             bian(x,y,(ll)v*ksm(u,mod-2)%mod);
35             bian(y,x,(ll)u*ksm(v,mod-2)%mod);
36         }
37         for(int i=1;i<=n;i++)
38         {
39             if(pd[i]==0)
40             {
41                 dis[i]=1;
42                 dfs(i,i);
43                 if(cuo==1) break;
44             }
45         }
46         printf("Case #%d: ",jjj);
47         if(cuo==0) printf("Yes\n");
48         else printf("No\n");
49     }
50     return 0;
51 }
52 ll ksm(ll x,ll y)
53 {
54     ll z=x,sum=1;
55     while(y)
56     {
57         if(y&1)
58             sum=sum*z%mod;
59         y>>=1;
60         z=z*z%mod;
61     }
62     return sum;
63 }
64 void bian(int x,int y,ll z)
65 {
66     e++;
67     l[e].u=x;
68     l[e].v=y;
69     l[e].d=z;
70     l[e].next=lian[x];
71     lian[x]=e;
72 }
73 void dfs(int x,int fa)
74 {
75     for(int i=lian[x];i;i=l[i].next)
76     {
77         int v=l[i].v;
78         if(v==fa) continue;
79         if(pd[v]==0)
80         {
81             dis[v]=dis[x]*l[i].d%mod;
82             pd[v]=1;
83             dfs(v,x);
84         }
85         else
86         {
87             ll d=ksm(dis[x],mod-2)*dis[v]%mod;
88             if(d!=l[i].d) cuo=1;
89         }
90     }
91 }
View Code

 

posted @ 2017-11-03 21:01  hzoi_wangxh  阅读(219)  评论(0编辑  收藏  举报