zoukankan      html  css  js  c++  java
  • Uva 11478 Halum操作

    题目链接:http://vjudge.net/contest/143318#problem/B

    题意:给定一个有向图,每条边都有一个权值。每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权值减小d,把所有以v为起点的边的权值增加d,最后让所有边的权值的最小值大于零且尽量大。

    分析:

    最小值尽量大,二分,最大不能超过最大边,要是最大边的话,其他边满足不了非负;

    题意说的各种操作,他互不影响;也就变成了操作各边。

    对于各点的操作来说:

    令sum(u) 是作用于 u 上的所有 d 之和;

    a—> b边的权值就是: w(a,b) +sum(a) - sum(b)>=x(答案);

    对上式 变形: sum(b) - sum(a) <= w(a,b) -x;

    sum(b) - sum(a) 就是对这条边的操作。

    这就是一个差分约束系统。

    枚举这个sum(b) - sum(a) ,要是有负环,就是查分系统无解。

    没有负环,说明,这个最小值还可以大一点。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 500 + 10;
    
    struct Edge
    {
        int from,to;
        double dist;
    };
    
    struct BellmanFord
    {
        int n, m;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool inq[maxn];
        double d[maxn];
        int p[maxn];
        int cnt[maxn];
    
        void init(int n)
        {
            this->n = n;
            for(int i = 0; i < n; i++) G[i].clear();
            edges.clear();
        }
    
        void AddEdge(int from, int to, double dist)
        {
            edges.push_back((Edge)
            {
                from, to, dist
            });
            m = edges.size();
            G[from].push_back(m-1);
        }
    
        bool negativeCycle()
        {
            queue<int> Q;
            memset(inq, 0, sizeof(inq));
            memset(cnt, 0, sizeof(cnt));
            for(int i = 0; i < n; i++)
            {
                d[i] = 0;
                inq[0] = true;
                Q.push(i);
            }
    
            while(!Q.empty())
            {
                int u = Q.front();
                Q.pop();
                inq[u] = false;
                for(int i = 0; i < G[u].size(); i++)
                {
                    Edge& e = edges[G[u][i]];
                    if(d[e.to] > d[u] + e.dist)
                    {
                        d[e.to] = d[u] + e.dist;
                        p[e.to] = G[u][i];
                        if(!inq[e.to])
                        {
                            Q.push(e.to);
                            inq[e.to] = true;
                            if(++cnt[e.to] > n) return true;
                        }
                    }
                }
            }
            return false;
        }
    };
    
    
    BellmanFord solver;
    
    bool test(int x)
    {
        for(int i=0; i<solver.m; i++)
        {
            solver.edges[i].dist -=x;
        }
        bool ret = solver.negativeCycle();
        for(int i=0; i<solver.m; i++)
        {
            solver.edges[i].dist +=x;
        }
        return !ret;
    }
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
    
            solver.init(n);
            int ub = 0;
    
            for(int i=0; i<m; i++)
            {
                int u,v,dist;
                scanf("%d%d%d",&u,&v,&dist);
                ub = max(ub,dist);
                u--;
                v--;
                solver.AddEdge(u,v,dist);
            }
    
            if(test(ub+1)) puts("Infinite");
            else if(!test(1)) puts("No Solution");
            else
            {
                int L = 2, R = ub, ans = 1;
                while(L <= R)
                {
                    int M = L + (R-L)/2;
                    if(test(M))     //没有负环
                    {
                        ans = M;
                        L = M+1;
                    }
                    else R = M-1;
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    sql 存储过程参数为空则不作为条件
    sql 将某一列转成字符串并且去掉最后一个逗号
    日期时间格式加减操作
    未能加载文件或程序集“NPOI”或它的某一个依赖项
    SqlBulkCopy 批量插入
    字符串操作
    CSS基本知识汇总
    ORACLE创建表之前判断表是否存在与SQL Server 对比使用
    SELECT INTO FROM 与 INSERT INTO SELECT区别鉴赏
    SQL 养成一个好习惯是一笔财富
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6115582.html
Copyright © 2011-2022 走看看