UVA 11478 bf+差分约束系统+二分逼近

Halum

You are given a directed graph G(V, E) with a set of vertices and edges. Each edge (i, j) that connects some vertex i to vertex j has an integer cost associated with that edge. Define the operation Halum(v, d) to operate on a vertex v using an integer d as follows: subtract d from the cost of all edges that enter v and add d to the cost of every edge that leaves v. As an example of that operation, consider graph G that has three vertices named (1, 2, 3) and two edges. Edge (1, 2) has cost -1, and edge (2,3) has cost 1. The operation Halum(2, −3) operates on edges entering and leaving vertex 2. Thus, edge (1, 2) gets cost -1-(-3)=2 and the edge (2, 3) gets cost 1 + (-3) = -2. Your goal is to apply the Halum function to a graph, potentially repeatedly, until every edge in the graph has at least a certain cost that is greater than zero. You have to maximize this cost.

Input

Two space-separated integers per case: V (V ≤ 500) and E (E ≤ 2700). E lines follow. Each line represents a directed edge using three space-separated integers (u, v, d). Absolute value of cost can be at most 10000.

Output

If the problem is solvable, then print the maximum possible value. If there is no such solution print ‘No Solution’. If the value can be arbitrary large print ‘Infinite’

Sample Input

2 1

1 2 10

2 1

1 2 -10

3 3

1 2 4

2 3 2

3 1 5

4 5

2 3 4

4 2 5

3 4 2

3 1 0

1 2 -1

Sample Output

Infinite

Infinite

3

1

思路:对于同一个节点,将多次操作合并,令sum(u)为u上所有节点的操作,问题转化为每条求权值均不小于x,对于a->b,操作完,它的权值为w(a,b)+sum(a)-sum(b)>=x,移项得sum(b)-sum(a)<=w(a,b)+x,得到可图个差分约束系统

差分约束系统可以用最短路径算法:对于约束条件xj-xi>=bk,新建一条边i->j,权值为bk,再加一个源点,从s出发与所有其他点相连,权值为0,再加一个源点s,从s出发与其他点相连,权值为0。在这个图上运行bf算法,则源点s到所有点i的距离就是xi的值。如果bf算法运行失败,即图中有负权环,则差分约束系统无解。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

//#define EdsonLin

#ifdef EdsonLin
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...)
#endif // EdsonLin

typedef long long ll;
typedef double db;
const ll inf = 10010;
const int MAXN = 500;
const int MAXNN = 3e3+10;
const ll MOD = 1000000007;
const db eps = 1e-3;

struct bf{
    int n,m;
    int first[MAXN];
    struct edge{
        int st,to,next,dist;
    }e[MAXNN];
    int top;
    int d[MAXN];
    int inq[MAXN];
    int cnt[MAXN];
   /* bf(int n){
        this->n = n;
        memset(first,-1,sizeof(first));
        top = 0;
    }*/
    void init(int n){
        this->n = n;
        memset(first,-1,sizeof(first));
        top = 0;
    }
    void addege(int u,int v,int dist){
        e[top].st = u;
        e[top].to = v;
        e[top].dist = dist;
        e[top].next = first[u];
        first[u] = top++;
    }
    bool negativeCycle(){
        queue<int>Q;
        for(int i=0;i<n;i++){
            Q.push(i);
            cnt[i] = inq[i] = d[i] = 0;
        }
        inq[0] = 1;
        while(!Q.empty()){
            int u=Q.front();
            Q.pop();
            inq[u] = 0;
            for(int i=first[u];i!=-1;i=e[i].next){
                int v = e[i].to;
                if(d[v]>d[u]+e[i].dist){
                    d[v] = d[u]+e[i].dist;
                    if(!inq[v]){
                        cnt[v]++;
                        inq[v] = 1;
                        Q.push(v);
                        if(cnt[v]>n){
                            //cout<<"haha"<<endl;
                            return true;
                        }
                    }
                }
            }
        }
        return false;;
    }
} solver;

bool solve(int x){
    bool sg;
    for(int i=0;i<solver.top;i++){
        solver.e[i].dist -= x;
        //cout<<solver.e[i].dist<<endl;
    }
    sg = solver.negativeCycle();
    for(int i=0;i<solver.top;i++){
        solver.e[i].dist += x;
       // cout<<solver.e[i].dist<<endl;
    }
    return sg;
}

int main()
{

    #ifdef EdsonLin
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        int _time_jc = clock();
    #endif // EdsonLin

    int n,m;
    while(cin>>n>>m){
        int u,v,dist;
        solver.init(n);
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&dist);
            u--;v--;
            solver.addege(u,v,dist);
        }
        if(!solve(inf)){
            cout<<"Infinite"<<endl;
            continue;
        }
        if(solve(1)){
            cout<<"No Solution"<<endl;
            continue;
        }
        int L,R,M;
        R = inf,L = 1;
        while(L<R){
            M = L+(R-L+1)/2;
            if(solve(M))R = M-1;
            else L = M;
        }
        cout<<L<<endl;

    }

    #ifdef EdsonLin
        debug("time: %d\n",int(clock()-_time_jc));
    #endif // EdsonLin
    //cout << "Hello world!" << endl;
    return 0;
}

bf模板

时间: 2024-10-24 02:18:55

UVA 11478 bf+差分约束系统+二分逼近的相关文章

UVA 11478 Bellman-Ford+差分约束系统

[题意]: 给出一张有向图(信息为点数,边数,每条边的起点终点和权值),然后可以让你做任意次如下操作: 选择任意节点v和一个数值d,使以v为终点的边的权值减d,以v为起点的边的权值加d, 最后要满足两个条件:这些边的权值为非负,这些边中权值最小的边的权值尽量大.[知识点]: Bellman-Ford+差分约束系统[题解]: 差分约束系统:是判断不等式组有解的一种方法(具体原理还不甚理解,以后还会具体补充该文章) 例如有若干不等式形如xj-xi<=ak 那么以i为起点j为终点ak为权值建图,然后用

UVA - 11478 Halum(差分约束系统)

题目大意:有一种操作(u,c),表示所有以u为终点的边的权值减去c,所有以u为起点的边权值加上c 最后要求所有的边的权值非负且尽量大 解题思路:最小且最大,二分,枚举边的最小权值,然后看是否符合 对于给出的所有有向线段(u,v,val) 所有对u和v的操作才会影响到这条边,对其他点的操作并不会影响到,所以可以将边分开出来讨论 假设对u的操作为d[u],对v的操作为d[v],那么这条边的权值就变成了 d[u] - d[v] + val 假设枚举的边权值为w,那么这条边就要满足 d[u] - d[v

UVA 11478 Halum (差分约束)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2473 题解: 首先我们可以得到的约束条件形如 xi - xj <= b[k] ,即可以转换为 j - > i连边,且权值为b[k],这样建图后我们判断是否有解,只需要用spfa跑负圈就可以了. 如果存在负圈,原差分系统定然无解. 简单证明: 我们不妨设这个环为 x1,

训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)

layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - BellmanFord - 图论 - 训练指南 - 差分约束 Halum UVA - 11478 题意 带权有向图,每个点都可以有如下操作:令从ta出发的每一条边增加d,终止于ta的每一条边减小d 最后让所有边权的最小值非负且尽量大 题

UVA 11478 Halum(差分约束系统+Bellman-Ford)

 题意:给定一个有向图,每条边都有一个权值.每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权值减小d,把所有以v为起点的边的权值增加d,最后让所有边的权值的最小值大于零且尽量大. ps:lrj的书上有个坑,说上说非负,其实原题说要大于0.....wa了好几发 分析:因为不同的操作互不影响,因此可以按任意顺序实施这些操作.另外,对于同一个点的多次操作可以合并,因此可以令sum(u)为作用于结点u之上的所有d之和.这样,本题的目标就是确定所有的sum(u),使得操作之后所有边权的最

uva 11478 Halum(图论-差分约束)

  Problem H Halum Time Limit : 3 seconds   You are given a directed graph G(V,E) with a set of vertices and edges. Each edge (i,j) that connects some vertex i to vertex j has an integer cost associated with that edge. Define the operation Halum(v, d)

UVA 11478 - Halum(差分约束+最短路)

UVA 11478 - Halum 题目链接 题意:给定一个有向图,每次操作可以选择一个结点,把以这个点为起点的边权值+d,以这个边为终点的-d,问经过操作后,能得到的边权最小的最大值是多少,并且要判但是否无穷大或无解 思路:转化为差分约束,设一条边,他增加的权值为sum(u)减少了sum(v),那么二分答案x,得到一个不等式sum(u) - sum(v) + w(u, v) >= x,变形后得到sum(v) - sum(u) <= w(u, v) - x,这样就转化为了差分约束,直接bell

UVA 11374 Halum (差分约束系统,最短路)

题意:给定一个带权有向图,每次你可以选择一个结点v 和整数d ,把所有以v为终点的边权值减少d,把所有以v为起点的边权值增加d,最后要让所有的边权值为正,且尽量大.若无解,输出结果.若可无限大,输出结果.否则,输出最小边权的最大值. 思路:差分约束系统用最短路来解.列式子后建图,新图的边就是原图的边,权值也不变.有3种情况,要分开判断. (1)若连最小的权值1都达不到,肯定无解. (2)若可以超过所给边的最大权值,那么最小权值肯定可以继续增大. (3)接下来用二分猜答案,答案范围在[1,big]

UVA 11478 Halum(差分约束)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34651 [思路] 差分约束系统. 设结点u上的操作和为sum[u],则边(u,v)权值为d-sum[v]+sum[u].对于最小值最大问题我们想到二分答案,设二分值为x,则问题变为判断最小值为x时题目是否存在解.对于权值我们有不等式d-sum[v]+sum[u]>=x  =>  sum[v]<=sum[u]+(d-x),由此可以建立差分约束系统. 无解:如