• 图论训练之六


    https://www.luogu.org/problem/P3275

    说说差分约束的套路吧

    关于建图的基本规律

    1.如x=y,则add(x,y,0), add(y,x,0)

    2.如x>y,则add(y,x,1)

    3.如x≤y,则add(x,y,0)

    4.如x<y,则add(u,v,1)

    5.如x≥y,则add(v,u,0)

    (其中边权根据题目而定)

    最短路边权为负,最长路边权为正,建议都只用最短路

    技巧一

    小于号那边的为起点

    技巧二

    统一符号,都为“<=”或都为"<=",方便计算最短路或最长路(注意我说的前后不一定对应)

    如果化简后式子和最短路松弛操作相同则为最长路,否则为最短路

    技巧三

    抠出隐藏条件,就如本题而言,每个小朋友必须得有糖果,即任意x>0,即0为超级源点

    
    #include<bits/stdc++.h>
    #define re register
    using namespace std;
    typedef long long ll;
    const ll N = 200011;
    const ll inf = 0x3f3f3f3f3f;
    ll n, T, cnt, ans, vis[N], len[N], head[N];
    struct edge {
        ll to, next, w;
    } e[N << 1];
    inline void add( ll u, ll v, ll w ) {
        e[++cnt].to = v, e[cnt].w = w,
        e[cnt].next = head[u], head[u] = cnt;
    }
    
    namespace IO {
    
        inline ll read() {
            ll x = 0; bool f = 0; char ch = getchar();
            for(; !isdigit( ch ); ch = getchar()) f^=( ch == '-' );
            for(; isdigit( ch ); ch = getchar()) x = ( x << 3 ) + ( x << 1 ) + ( ch ^ 48 );
            return f? -x: x;
        }
    
        inline void write( ll x ) {
            if( x < 0 ) { putchar( '-' ); x = -x; }
            if( x > 9 ) write( x / 10 );
            putchar( x % 10 | 48 );
        }
    
        inline void wln( ll x ) { write( x ); putchar( '
    ' ); }
    
    }
    
    using namespace IO;
    inline bool Spfa( ll u ) {//dfs版的spfa更好
        vis[u] = 1;
        for( re int i = head[u]; i; i = e[i].next ) 
            if( len[e[i].to] > len[u] + e[i].w ) {
                len[e[i].to] = len[u] + e[i].w;
                if( vis[e[i].to] || !Spfa( e[i].to ) ) return 0;
            }
        vis[u] = 0; return 1;
    }
    
    int main() {
        n = read(), T = read();
        while( T-- ) {
            ll opt = read(), a = read(), b = read();
            switch( opt ) {
                case 1: add( a, b, 0 ); add( b, a, 0 ); break;
                case 2: if( a == b ) return !puts("-1"); add( a, b, -1 ); break;//特判两者相等的情况
                case 3: add( b, a, 0 ); break;
                case 4: if( a == b ) return !puts("-1"); add( b, a, -1 ); break;//同理特判
                case 5: add( a, b, 0 ); break;
            }
        }
    
        for( int i=n;i>=1;i--) add(0,i,-1),len[i]=inf;len[0] = 0;//超级源点
        if( Spfa(0) ) {
           for(int i=1;i<=n;i++)ans -= len[i];//值为负,所以要减去
            return wln( ans ), 0;
        } else return !puts("-1");
    }
    
  • 相关阅读:
    菜根谭#188
    菜根谭#187
    Single value range only allowed in SystemVerilog
    LUTs, Flip-Flop, Slice
    FPGA 的 RAM 的 区别
    GPU core clock, shader clock ???
    更改Mac的Terminal 格式
    GPU share memory 的应用 (主要内容转载)
    Mac text edit & pdf reader
    Programming Font
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11627371.html
Copyright © 2020-2023  润新知