Aizu2971 Consistent Trading

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2971

\(Hash\)

显然,我们可以连边成为一个图,\(u \rightarrow v\)权值为\(z\),则\(v \rightarrow u\)权值为\(\frac{1}{z}\)

那么从任意起点\(s\)到任意终点\(t\)的路径(边权乘积)为兑换关系

显然,对于确定的\(s\)\(t\),其兑换关系必须相同

所以只有\(s\)\(t\)的所有路径相同,才能满足题意

\(BFS\)一下,判断类似\(Dijkstra\)

还有一个问题,边权乘积太大,而且还有分数,怎么办?

\(Hash!\)

这样分数也可以用逆元处理了

注意要多模数,取了\(3\)个才过

本来应该写函数的,但是我把代码复制\(3\)遍,代码巨长

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#define N 200005
#define INF 12345678987654321
#define mod1 1000000007
#define mod2 1000000009
#define mod3 39999931
#define ll long long
#define int long long
#define pr pair<ll,int>
using namespace std;
queue<pr>q;
int n,m,tot,x,y,z,in[N];
int head[N],d1[N],d2[N],d3[N],nxt[N],e[N][3];
ll dis[N];
bool vis[N],Previs[N];
ll ksm1(ll x,ll y)
{
    ll ans=1;
    while (y)
    {
        if (y&1)
            ans=ans*x%mod1;
        x=x*x%mod1;
        y >>=1;
    }
    return ans;
}
ll inv1(ll x)
{
    return ksm1(x,mod1-2);
}
ll ksm2(ll x,ll y)
{
    ll ans=1;
    while (y)
    {
        if (y&1)
            ans=ans*x%mod2;
        x=x*x%mod2;
        y >>=1;
    }
    return ans;
}
ll inv2(ll x)
{
    return ksm2(x,mod2-2);
}
ll ksm3(ll x,ll y)
{
    ll ans=1;
    while (y)
    {
        if (y&1)
            ans=ans*x%mod3;
        x=x*x%mod3;
        y >>=1;
    }
    return ans;
}
ll inv3(ll x)
{
    return ksm3(x,mod3-2);
}
void add(int x,int y,int z)
{
    tot++;
    d1[tot]=y;
    d2[tot]=z;
    nxt[tot]=head[x];
    head[x]=tot;
}
void Clear()
{
    tot=0;
    memset(head,0,sizeof(head));
    memset(vis,false,sizeof(vis));
    memset(Previs,false,sizeof(Previs));
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        e[i][0]=x,e[i][1]=y,e[i][2]=z;
        add(x,y,z);
        add(y,x,inv1(z));
    }
    for (int i=1;i<=n;i++)
        dis[i]=0;
    for (int i=1;i<=n;i++)
        if (!vis[i])
        {
            in[0]=0;
            while (!q.empty())
                q.pop();
            dis[i]=1;
            q.push(make_pair(1,i));
            while (!q.empty())
            {
                pr u=q.front();
                q.pop();
                if (Previs[u.second])
                    continue;
                vis[u.second]=true;
                in[++in[0]]=u.second;
                for (int j=head[u.second];j;j=nxt[j])
                {
                    int v=d1[j],cost=d2[j];
                    if (Previs[v])
                        continue;
                    ll o=dis[u.second]*cost%mod1;
                    if (o!=dis[v]&&dis[v]!=0)
                    {
                        puts("No");
                        return 0;
                    }
                    if (dis[v]==0)
                        q.push(make_pair(o,v));
                    dis[v]=o;
                }
            }
            for (int j=1;j<=in[0];j++)
                Previs[in[j]]=true;
        }


    Clear();

    for (int i=1;i<=m;i++)
    {
        add(e[i][0],e[i][1],e[i][2]);
        add(e[i][1],e[i][0],inv2(e[i][2]));
    }

    for (int i=1;i<=n;i++)
        dis[i]=0;
    for (int i=1;i<=n;i++)
        if (!vis[i])
        {
            in[0]=0;
            while (!q.empty())
                q.pop();
            dis[i]=1;
            q.push(make_pair(1,i));
            while (!q.empty())
            {
                pr u=q.front();
                q.pop();
                if (Previs[u.second])
                    continue;
                vis[u.second]=true;
                in[++in[0]]=u.second;
                for (int j=head[u.second];j;j=nxt[j])
                {
                    int v=d1[j],cost=d2[j];
                    if (Previs[v])
                        continue;
                    ll o=dis[u.second]*cost%mod2;
                    if (o!=dis[v]&&dis[v]!=0)
                    {
                        puts("No");
                        return 0;
                    }
                    if (dis[v]==0)
                        q.push(make_pair(o,v));
                    dis[v]=o;
                }
            }
            for (int j=1;j<=in[0];j++)
                Previs[in[j]]=true;
        }

    Clear();

    for (int i=1;i<=m;i++)
    {
        add(e[i][0],e[i][1],e[i][2]);
        add(e[i][1],e[i][0],inv3(e[i][2]));
    }

    for (int i=1;i<=n;i++)
        dis[i]=0;
    for (int i=1;i<=n;i++)
        if (!vis[i])
        {
            in[0]=0;
            while (!q.empty())
                q.pop();
            dis[i]=1;
            q.push(make_pair(1,i));
            while (!q.empty())
            {
                pr u=q.front();
                q.pop();
                if (Previs[u.second])
                    continue;
                vis[u.second]=true;
                in[++in[0]]=u.second;
                for (int j=head[u.second];j;j=nxt[j])
                {
                    int v=d1[j],cost=d2[j];
                    if (Previs[v])
                        continue;
                    ll o=dis[u.second]*cost%mod3;
                    if (o!=dis[v]&&dis[v]!=0)
                    {
                        puts("No");
                        return 0;
                    }
                    if (dis[v]==0)
                        q.push(make_pair(o,v));
                    dis[v]=o;
                }
            }
            for (int j=1;j<=in[0];j++)
                Previs[in[j]]=true;
        }

    puts("Yes");
    return 0;
}
posted @ 2020-07-25 15:09  GK0328  阅读(182)  评论(0编辑  收藏  举报