zoukankan      html  css  js  c++  java
  • [BZOJ 3126] Photo

    [题目链接]

            https://www.lydsy.com/JudgeOnline/problem.php?id=3126

    [算法]

            差分约束系统

            注意SPFA判负环的条件应为 : 若所有点入队次数之和 > 点数 + 边数,说明有负环

    [代码]

           

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 200010
    const int inf = 2e9;
    
    int n,m,tot;
    int head[MAXN];
    
    struct edge
    {
        int to,w,nxt;
    } e[MAXN << 2];
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-')  f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int u,int v,int w)
    {
        tot++;
        e[tot] = (edge){v,w,head[u]};
        head[u] = tot;
    }
    inline int spfa(int s)
    {
        int l,r,cnt = 0;
        static int dist[MAXN];
        static bool inq[MAXN];
        priority_queue< int , vector< int > , greater< int > > q;
        while (!q.empty()) q.pop();
        for (register int i = 0; i <= n; i++)
        {
            dist[i] = inf;
            inq[i] = false;
        }
        q.push(s);
        dist[s] = 0;
        inq[s] = true;
        cnt = 1;
        while (!q.empty())
        {
            int u = q.top();
            q.pop();
            inq[u] = false;
            for (register int i = head[u]; i; i = e[i].nxt)
            {
                int v = e[i].to , w = e[i].w;
                if (dist[u] + w < dist[v])
                {
                    dist[v] = dist[u] + w;
                    if (!inq[v])
                    {
                        cnt++;
                        if (cnt > 3 * m + 2 * n) return -1;
                        inq[v] = true;
                        q.push(v);
                    }
                }
            }
        }
        return dist[n] == inf ? -1 : dist[n];
    }
    
    int main()
    {
        
        read(n); read(m);
        for (register int i = 1; i <= m; i++) 
        {
            int a,b;
            read(a); read(b);
            if (a > b) swap(a,b);
            addedge(a - 1,b,1);
            addedge(b,a - 1,-1);
        }
        for (register int i = 1; i <= n; i++) 
        {
            addedge(i,i - 1,0);
            addedge(i - 1,i,1);
        }
        printf("%d
    ",spfa(0));
        
        return 0;
    }
  • 相关阅读:
    如何让自己的app尽量不被系统杀死
    linux常用命令-权限管理命令
    linux常用命令-用户管理命令
    linux常用命令-文件处理命令
    npm命令
    新技术新框架新工具选型原则
    tomcat启动命令行中文乱码
    docker命令
    tinkpad e450c 进入 BIOS
    基于Java服务的前后端分离解决跨域问题
  • 原文地址:https://www.cnblogs.com/evenbao/p/9511536.html
Copyright © 2011-2022 走看看