zoukankan      html  css  js  c++  java
  • [Luogu 3275] SCOI2011 糖果

    [Luogu 3275] SCOI2011 糖果

    <题目链接>


    第一道差分约束。感谢 AZe。

    我的理解是根据一些不等关系建一个图,在图上边跑一个最长路(有时候是最短路)。

    因为可能存在负环,所以必须用 SPFA!

    好神奇啊,图论好强强啊。

    然而 Capella 惨惨,用上了 0 号节点却从 1 开始初始化邻接表,导致 for 出不去了,就因为这个调了一个晚上。

    指针选手初始化很重要啊。

    加油qwq

    #include <algorithm>
    #include <cstdio>
    #include <queue>
    
    #define nullptr NULL
    
    const int MAXN = 100010; 
    
    int n, k; 
    long long ans; 
    
    struct Graph
    {
        struct Edge
        {
            int to; 
            long long w; 
            Edge *next; 
            Edge(int to, long long w, Edge* next): to(to), w(w), next(next) {}
            ~Edge(void)
            {
                if(next != nullptr)
                    delete next; 
            }
        }*head[MAXN]; 
        Graph(int n)
        {
            std :: fill(head, head + n + 1, (Edge*)nullptr); 
        }
        ~Graph(void)
        {
            for(int i = 1; i <= n; ++i)
                delete head[i]; 
        }
        void AddEdge(int u, int v, long long w)
        {
            head[u] = new Edge(v, w, head[u]); 
        }
        void Build(int x, int a, int b)
        {
            if(x % 2 == 0 && a == b)
            {
                puts("-1"); 
                exit(0); 
            }
            switch(x)
            {
                case 1: 
                    AddEdge(a, b, 0LL); 
                    AddEdge(b, a, 0LL); 
                    break; 
                case 2: 
                    AddEdge(a, b, 1LL); 
                    break; 
                case 3: 
                    AddEdge(b, a, 0LL); 
                    break; 
                case 4: 
                    AddEdge(b, a, 1LL); 
                    break; 
                case 5: 
                    AddEdge(a, b, 0LL); 
                    break; 
            }
        }
    }*G; 
    
    namespace DiffConst
    {
        bool exist[MAXN]; 
        int cnt[MAXN]; 
        long long dist[MAXN]; 
        bool SPFA(int S)
        {
            std :: queue<int> Q; 
            Q.push(S); 
            exist[S] = true; 
            while(!Q.empty())
            {
                int u = Q.front(), v; 
                Q.pop(); 
                exist[u] = false; 
                for(Graph :: Edge *i = G -> head[u]; i != nullptr; i = i -> next)
                    if(dist[v = i -> to] < dist[u] + i -> w)
                    {
                        if(!exist[v])
                        {
                            if(++cnt[v] == n)
                                return false; 
                            Q.push(v); 
                            exist[v] = 1; 
                        }
                        dist[v] = dist[u] + i -> w; 
                    }
            }
            return true; 
        }
    }
    
    int main(void)
    {
        scanf("%d %d", &n, &k); 
        G = new Graph(n); 
        for(int i = 1, x, a, b; i <= k; ++i)
        {
            scanf("%d %d %d", &x, &a, &b); 
            G -> Build(x, a, b); 
        }
        for(int i = n; i >= 1; --i)
            G -> AddEdge(0, i, 1LL); 
        if(DiffConst :: SPFA(0))
        {
            for(int i = 1; i <= n; ++i)
                ans += DiffConst :: dist[i]; 
            printf("%lld
    ", ans); 
        }
        else
            puts("-1"); 
        return 0; 
    }
    

    谢谢阅读。

  • 相关阅读:
    20201220第二周学习总结
    师生关系
    快速浏览教材
    学期2020-2021-1学号20201220《信息安全专业导论》第1周学习总结
    编程将字符串s倒序输出,要求利用函数递归实现
    小学生四则运算随机生成程序
    礼炮问题
    C语言最大公约数
    C语言判断三角形类型
    C语言:一元二次方程解的所有情况
  • 原文地址:https://www.cnblogs.com/Capella/p/9899247.html
Copyright © 2011-2022 走看看