《算法周练4》A题解

[SDOI2016]齿轮

https://ac.nowcoder.com/acm/contest/5505/A

题意:问的是给定比例的齿轮能否旋转.
思路:首先,如果这个齿轮不成环,那么肯定可以通过相邻的齿轮转动.
所以我们需要的是判断成环的时候是否也能够转动.
首先,我们dfs时进行赋值,通过这个比例来赋值,让起始点为1.0即可.
然后当我们第二次来到这个点时,它已经判断下成环后重新赋的值和之前赋的值是否一样,一样就说明可以一起旋转.
不一样说明无法旋转.
实现上,我们成环后判断的只是起始点,然后就不再继续dfs,保证了不会死循环.

Code:
double eps = 1e-6;
struct Node
{
    int to;
    double x,y;
};
vector<Node> G[1005];
double w[1005];
int vis[1005],f;
void dfs(int u,int fa)
{
    vis[u] = 1;
    for(int i=0;i<G[u].size();++i)
    {
        int y = G[u][i].to;
        double x = G[u][i].x,yy = G[u][i].y;
        if(y == fa) continue;
        if(!vis[y]) 
        {
            w[y] = w[u]*yy/x;
            dfs(y,fa);
        }
        else//成环后遍历到
        {
            double cal = w[u]*yy/x;
            if(abs(w[y]-cal) > eps)
            {
                f = 1;
                return ;
            }
        }
    }
}
int main()
{
    int t,ca = 0;sd(t);
    while(t--)
    {
        int n,m;sdd(n,m);
        for(int i=1;i<=n;++i) G[i].clear();
        while(m--)
        {
            int u,v;
            double x,y;
            cin >> u >> v >> x >> y;
            G[u].push_back(Node{v,x,y});
            G[v].push_back(Node{u,y,x});
        }
        f = 0;
        met0(vis);
        for(int i=1;i<=n;++i)
        {
            if(f) break;
            if(!vis[i])
            {
                w[i] = 1.0;
                dfs(i,0);
            }
        }
        if(f) printf("Case #%d: No\n",++ca);
        else printf("Case #%d: Yes\n",++ca);
    }
    system("pause");
    return 0;
}
全部评论
大佬能解释一下赋值这部分吗, 有点懵😵
点赞 回复 分享
发布于 2022-03-31 11:02

相关推荐

喜欢吃蛋糕仰泳鲈鱼是我的神:字节可以找个hr 给你挂了,再放池子捞
点赞 评论 收藏
分享
11-15 18:39
已编辑
西安交通大学 Java
全村最靓的仔仔:卧槽,佬啥bg呢,本也是西交么
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务