• HNOI2005狡猾的商人-差分约束系统


    这个题可以用并查集做,这里是之前一个图论学傻了的蒟蒻的差分约束做法。。

    我们考虑题面中的条件,

    若s到t的为w,就相当于sum[t]-sum[s-1]=w。

    那么就是sum[t]-sum[s-1]>=w,sum[t]-sum[s-1]<=w,

    同时化成最短路松弛形式得到:sumt[s-1]+w<=sum[t],sum[t]+(-w)<=sum[s-1]。

    那么容易发现,只需要从s-1向t连一条w的边,再从t向s-1连一条-w的边就好了。

    最后就是直接spfa判环就好了。

    #include <bits/stdc++.h>
    using namespace std;
    inline int gi () {
        int x=0,w=0;char ch=0;
        while(!(ch>='0'&&ch<='9')) {
            if(ch=='-') w=1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
        return w?-x:x;
    }
    
    const int N=110;
    const int M=2010;
    bool inq[N];
    queue <int> q;
    int w,n,m,s,end,Sum,tot,flag,cnt[N],vis[N],head[N],val[N];
    
    struct edge {
        int next, now, ver;
    }e[M];
    
    void make (int from, int to, int v) {
        e[++tot].next=head[from];
        head[from]=tot;
        e[tot].now=to;
        e[tot].ver=v;
    }
    
    bool SPFA (int k) {
        memset (val,-0x3f3f3f3f,sizeof (val));
        memset (cnt,0,sizeof (cnt));
        memset (inq,0,sizeof (inq));
        q.push (k);
        inq[k]=1, val[k]=0;
        int x,y,i;
        while (!q.empty ()) {
            x=q.front ();
            q.pop (), inq[x]=0, vis[x]=1;
            for (i=head[x];i;i=e[i].next) {
                y=e[i].now;
                if (val[x]+e[i].ver>val[y]) {
                    if (++cnt[y]>=n) return 0;
                    val[y]=val[x]+e[i].ver;
                    if (!inq[y]) q.push (y), inq[y]=1;
                }
            }
        }
        return 1;
    }
    
    int main ()
    {
        w=gi ();
        while (w--) {
            n=gi (), m=gi ();
            tot=0; flag=0;
            memset (head,0,sizeof (head));
            memset (vis,0,sizeof (vis));
            memset (&e,0,sizeof (e));
            for (int i=1;i<=m;++i) {
                s=gi (), end=gi (), Sum=gi ();
                make (s-1, end, Sum), make (end, s-1, -Sum);
            }
            for (int i=0;i<=n;++i) {
                if (vis[i]) continue;
                if (!SPFA (i)) {
                    flag=1;
                    break;
                }
            }
            flag?printf ("false
    "):printf ("true
    ");
        }
        
        return 0;
    }

     带权并查集还是比这个快了不少,贴波代码

    #include <string>
    #include <cstdio>
    #include <cstring>
    #define IL inline 
    #define RG register
    #define LL long long
    using namespace std;
    
    IL int gi () {
        RG int x=0,w=0; char ch=0;
        while (ch<'0'||ch>'9') {if (ch=='-') w=1; ch=getchar();}
        while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
        return w?-x:x;
    }
    
    const int N=110;
    
    int fa[N],dis[N];
    
    int get_fa (int x) {
        if (x==fa[x]) return x;
        RG int fx=fa[x];
        fa[x]=get_fa (fa[x]);
        dis[x]+=dis[fx];
        return fa[x];
    }
    
    int main ()
    {
        RG int T,n,m,s,t,v,i,flag;
        T=gi ();
        while (T--) {
        n=gi(),m=gi(),flag=0;
        memset (fa,0,sizeof(fa));
        memset (dis,0,sizeof(dis));
        for (i=1;i<=n;++i) fa[i]=i;
        while (m--) {
            s=gi()-1,t=gi(),v=gi();
            RG int fas=get_fa(s),fat=get_fa(t);
            if (fas==fat) {
            if (dis[t]!=dis[s]+v) flag=1;
            }
            else fa[fat]=fas,dis[fat]=dis[s]-dis[t]+v;
        }
        puts(flag?"false":"true");
        }
        return 0;
    }
  • 相关阅读:
    ARCGIS JAVASCRIPT API (3.2)部署
    WINFORM 只能运行一个实例问题
    iOS 版本号
    同步和异步的区别
    简单的手机号判断
    "_inflateEnd", referenced from "_inflateInit_"等。这时需要在工程中加入libz.dlib 文件
    iOS 实现打电话
    assign retain copy iOS
    iOS 长按事件 UILongPressGestureRecognizer
    UITableView 滑动删除
  • 原文地址:https://www.cnblogs.com/Bhllx/p/9928995.html
Copyright © 2020-2023  润新知