UVA 11478(差分约束 + 二分)


题意:

给定一个有向图,每条边都有一个权值,每次你可以选择一个结点和一个整数的,把所有以v为终点的边的权值减去d,

把所有以v为起点的边的权值加上d

最后要让所有边的权的最小值非负且尽量大

代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N = 1e3;
const int inf  = 0x3f3f3f3f;
int dist[N],inq[N],cnt[N];
struct node
{
    int v,w;
    node(int v,int w):v(v),w(w) {};
};
vector<node> G[N];
void init(int n)
{
    for(int i = 0; i<=n; i++) G[i].clear();
}
bool spfa(int n)
{
    queue<int> q;
    q.push(0);
    memset(inq,0,sizeof(inq));
    memset(cnt,0,sizeof(cnt));
    memset(dist,inf,sizeof(dist));
    dist[0] = 0;
    inq[0] = 1;
    cnt[0] = 1;
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        inq[u] = 0;
        for(int i = 0; i<G[u].size(); i++)
        {
            int v = G[u][i].v, w= G[u][i].w;
            if(dist[v]>dist[u] + w)
            {
                dist[v] = dist[u] + w;
                if(!inq[v]) q.push(v),inq[v] = 1;
                if(++cnt[v]>n) return true;
            }
        }
    }
    return false;
}
bool test(int mid,int n)
{
    for(int i = 1; i<=n; i++)
        for(int j = 0; j<G[i].size(); j++)
            G[i][j].w -=mid;
    int ret = spfa(n);
    for(int i = 1; i<=n; i++)
        for(int j = 0; j<G[i].size(); j++)
            G[i][j].w +=mid;
    return ret;
}
int main()
{
    int V,E;
    while(~scanf("%d%d",&V,&E))
    {
        init(V);
        int ub = 0;
        int u ,v ,w;
        for(int i = 0; i<E; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            G[u].push_back(node(v,w));
            ub = max(w,ub);
        }
        for(int i = 1; i<=V; i++)
            G[0].push_back(node(i,0));
        int L = 1, R = ub;
        if(test(L,V)) puts("No Solution");
        else if(!test(ub+1,V)) puts("Infinite");
        else
        {
            while(L<R)
            {
                int mid = L + (R -L)/2;
                if(test(mid,V)) R = mid ;
                else  L = mid + 1;
            }
            printf("%d\n",L-1);
        }
    }
    return 0;
}

时间: 2024-08-07 09:57:28

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

poj 1275 Cashier Employment - 差分约束 - 二分答案

A supermarket in Tehran is open 24 hours a day every day and needs a number of cashiers to fit its need. The supermarket manager has hired you to help him, solve his problem. The problem is that the supermarket needs different number of cashiers at d

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

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)

codevs 1183 泥泞的道路 (二分+SPFA+差分约束)

/* 二分答案(注意精度) 对于每一个答案 有(s1+s2+s3...)/(t1+t2+t3...)>=ans 时符合条件 这时ans有变大的空间 对于上述不等式如果枚举每一条路显得太暴力 化简一下变成 :s1-t1*ans+s2-t2*ans+s3-t3*ans...>=0 差分约束跑最长路 如果dis[n]>0 或者有正环 (开始这个忘掉了)ans就合法 */ #include<iostream> #include<cstdio> #include<cs

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

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

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

POJ1275 Cashier Employment 【二分 + 差分约束】

题目链接 POJ1275 题解 显然可以差分约束 我们记\(W[i]\)为\(i\)时刻可以开始工作的人数 令\(s[i]\)为前\(i\)个时刻开始工作的人数的前缀和 每个时刻的要求\(r[i]\),可以通过如下限制满足: \[s[i] - s[i - 8] \ge r[i]\] \[0 \le s[i] - s[i - 1] \le W[i]\] 但是\(i - 8\)可能为负,回到上一天的时刻,导致区间不连续,不好处理 我们可以二分答案\(sum\) 将\(i < 8\)的部分改为: \[

差分约束小结

ZOJ 2770 Burn the Linked Camp /* ZOJ 2770 Burn the Linked Camp 差分约束 */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int MAXN = 1009; struct Edge { int v, ne, c; } G[MAXN*MAXN]