zoukankan      html  css  js  c++  java
  • [代码]SGU 298 King Berl VI

    很裸很简单的差分约束题,如果你知道这个。先用正图求最大解,再用反图求最小解,若某个点v的最大解<最小解,则No solution。题目要求x[N]-x[1]最小,那就令x[N]为其最小解,x[1]为其最大解,再spfa一遍就好。

    我的代码之所以跑了1s多是因为边都是非正权边,其他人在spfa之前用dfs判负环,我直接用spfa判……

    ====

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    const int INF = 10000;
    const int MAXV = 10010;
    const int MAXE = 100010;
    
    struct se
    {int v, d, next;};
    
    se g[MAXE], r[MAXE];
    int disg[MAXV], disr[MAXV];
    int fg[MAXV], fr[MAXV];
    int N, M, E=0;
    int t[MAXV];
    bool inq[MAXV];
    deque<int> q;
    
    void ae(int u, int v, int d)
    {
        g[E].v = v; r[E].v = u;
        g[E].d = d; r[E].d = d;
        g[E].next = fg[u]; r[E].next = fr[v];
        fg[u] = E; fr[v] = E++;
    }
    
    bool spfa(int N, se e[], int f[], int dis[])
    {
        int u, v, d, i;
        q.clear();
        for (u = 1; u <= N; ++u)
        {
            t[u] = 0;
            inq[u] = 1;
            q.push_back(u);
        }
        while (!q.empty())
        {
            u = q.front();
            q.pop_front();
            inq[u] = 0;
            for (i = f[u]; i != -1; i = e[i].next)
            {
                v = e[i].v; d = e[i].d;
                //printf("!%d %d %d %d %d %d\n", u, v, d, dis[u], dis[v], dis[v]<dis[u]+d);
                if (dis[v] > dis[u]+d)
                {
                    dis[v] = dis[u]+d;
                    if (!inq[v])
                    {
                        inq[v] = 1;
                        q.push_back(v);
                        ++t[v];
                        if (t[v] > N) return 0;
                    }
                }
            }
        }
        return 1;
    }
    
    int main()
    {
        int i, j, k, u, v, d;
        memset(fg, -1, sizeof(fg));
        memset(fr, -1, sizeof(fr));
        cin>>N>>M;
        while (M--)
        {
            scanf("%d%d%d", &u, &v, &d);
            ae(u, v, -d);
        }
        for (u = 1; u <= N; ++u)
            disg[u] = INF;
        if (!spfa(N, g, fg, disg))
        {
            puts("-1");
            return 0;
        }
        for (u = 1; u <= N; ++u)
            disr[u] = INF;
        if (!spfa(N, r, fr, disr))
        {
            puts("-1");
            return 0;
        }
        for (u = 1; u <= N; ++u)
            if (disg[u]<-disr[u])
            {
                puts("-1");
                return 0;
            }
        disg[N] = -disr[N];
        spfa(N, g, fg, disg);
        for (u = 1; u <= N; ++u)
            printf("%d ", disg[u]);
        return 0;
    }
  • 相关阅读:
    学生管理
    数据类型
    Linux安装、发布Django项目
    函数式编程
    学生管理系统
    mysql数据库工具类
    python操作数据库
    链接mysql建库建表
    列表元组字典集合
    内置对象相关方法
  • 原文地址:https://www.cnblogs.com/jffifa/p/2500972.html
Copyright © 2011-2022 走看看