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,x2...xn

即有不等式 x1 <= x2 + y1 , x2 <= x3 + y2 ..... xn <= x 1 + yn

全部累加得 0 <= sigma (y)

所以有解必须满足sigma(y) >= 0 ,如果存在负圈,肯定是无解的.

那么对于原图,如何判断infinate的情况呢?

注意到约束条件必须是环,所以我们只需要检测一下图中是否有环就可以了.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 5e2 + 50;
const double eps = 1e-6;
struct Edge{int v , nxt , w;};
Edge e[maxn * 6];
int n , m , head[maxn] , tot , cnt[maxn] ,inq[maxn] ,d[maxn],c[maxn];
queue<int>q;
void addedge(int u,int v,int w){e[tot].v=v,e[tot].nxt=head[u],e[tot].w=w,head[u]=tot++;}

void edge_init(int x)
{
    for(int i = 0 ; i < tot ; ++ i) e[i].w += x;
}

bool check()
{
    while(!q.empty()) q.pop();
    memset(cnt , 0 , 4 * (n + 1));
    memset( d , 0 , 4 * (n + 1) );
    for(int i = 1 ; i <= n ; ++ i)
    {
        inq[i] = 1;
        q.push(i);
    }
    while(!q.empty())
    {
        int x = q.front();q.pop();inq[x]=0;
        for(int i = head[x] ; ~i ; i = e[i].nxt)
        {
            int v = e[i].v;
            double neww = d[x] + e[i].w;
            if(neww < d[v])
            {
                d[v] = neww;
                if(!inq[v])
                {
                    inq[v] = 1;
                    if(++cnt[v] > n) return true;
                    q.push(v);
                }
            }
        }
    }
    return false;
}

bool dfs(int u)
{
    c[u]=-1;
    for(int i = head[u] ; ~i ; i = e[i].nxt)
    {
        int v = e[i].v;
        if(c[v]==1) continue;
        if(c[v]==-1) return true;
        if(dfs(v)) return true;
    }
    c[u]=1;
    return false;
}

int main(int argc,char *argv[])
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(head,-1,4*(n+1));tot=0;memset(c , 0 , 4 * (n + 1));
        for(int i = 0 ; i < m ; ++ i)
        {
            int u ,v,w ;scanf("%d%d%d",&u,&v,&w);
            addedge( u , v, w);
        }
        int flag = 0;
        for(int i = 1 ; i <= n ; ++ i)
            if(c[i]==0)
                if(dfs(i))
                {
                    flag=1;
                    break;
                }
        if(!flag)
        {
            printf("Infinite\n");
            continue;
        }
        int L = 0 , R = 20000;
        while(L < R)
        {
            int mid = L + (R-L+1)/2;
            edge_init(-mid);
            if(check()) R = mid-1;
            else L = mid;
            edge_init(mid);
        }
        edge_init(-L);
        if(L == 0 || check()) printf("No Solution\n");
        else printf("%d\n",L);
    }
    return 0;
}
时间: 2024-08-27 15:05:33

UVA 11478 Halum (差分约束)的相关文章

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(差分约束+最短路)

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 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 Bellman-Ford+差分约束系统

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

UVa11478 - 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 (最短路应用+二分)

Description   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 operati

UVA 11478 Halum

Halum Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 1147864-bit integer IO format: %lld      Java class name: Main You are given a directed graph G(V,E) with a set of vertices and edges. Each edge (i,j) th

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),由此可以建立差分约束系统. 无解:如

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

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