对于一个有向带权图,进行一种操作(v,d),对以点v为终点的边的权值-d,对以点v为起点的边的权值+d。现在给出一个有向带权图,为能否经过一系列的(v,d)操作使图上的每一条边的权值为正,若能,求最小边权的最大值。

不得不说,图论与动态规划的产物实在是神奇!!

1、既然是“最小值最大”问题,容易想到二分答案。

2、抽象出数学模型。这个在《训练指南》里写得已经很详细,鄙人还是以自己的理解表达一下。

  这里有两处特别值得学习的地方。一、叠加:假设每个点都对应着一个(v,d)操作,那么对于边u->v来说,受到两个端点的影响,最终的权值为(c+du-dv)。二、抽象:这个没学过差分约束真心想不到。之前想到了二分答案,那么我们假设最终的“最小值最大”为x,那么所有边满足(c+du-dv)>=x,变形后(dv-du)<=(c-x)。由于是第一次做这种类型的题,无法妄下结论,但书上所说到的“最短路中的不等式d[v]<=d[u]+w(u,v)”,很明显,我们常用的的不等式是d[v]>=d[u]+w(u,v)。所以,这里先记住这个模型:形如xj-xi

<=b,建边i->j,边权为b。(提出疑问:若得到的模型为xi-xj>=b,变形后xj-xi<=-b => 建边i->j,边权为-b)。

  至于书上说的"加源点s",完全不知为何物= =。不过不妨碍我们做题。由于采用二分答案,边权c是变值,处理方式很直白的把所有的边-x,判完负环再做+x就好了。

  为何判负环就可行呢?我们通过二分答案,改变b的值,每次都得到了一个的形如xj-xi<=b的不等式组,当不等式组不成立即说明当前二分的值不成立。举个例子:有个环1->2,2->3,3->1,对应的不等式x2-x1<=ca,x3-x2<=cb,x1-x3<=cc,若这是个负环,说明等式右侧(ca+cb+cc)<0,而等式左侧=0,为恒不等式。所以一旦存在负环,不等式组不成立,差分约束系统无解。

注意:

1、先做完特判,再处理其他数据,这点是通用的。(我一开始把判“No Solution”放在二分后面了,TLE。当然现在也不过是飘过时限= =)

  判“Inf”,无环,就不会在同一个圈中两两影响。判“No”要用1而不能是0,因为最后求得是正数。

2、二分写得时候要注意,要绝对防止 l,r 在相邻两个数之间不变。e.g:第三组样例,l=3,r=4,x作为中间值,当x==3,成立=>l=x;当x==4,不成立=>r=x。死循环了(偶真是弱爆了,明明很简单的问题还要想半天)

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define clr(a,m) memset(a,m,sizeof(a))
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int MAXN=;
const int INF =1e8; struct Edge{
int u,v,c;
}; int inq[MAXN],cnt[MAXN],d[MAXN];
vector<Edge>edge;
vector<int>G[MAXN]; void init(int n)
{
edge.clear();
rep(i,,n)
G[i].clear();
} void add(int u,int v,int c)
{
edge.push_back((Edge){u,v,c});
int m=edge.size();
G[u].push_back(m-);
} double build(int m)
{
int u,v;
int c,up=;
rep(i,,m){
scanf("%d%d%d",&u,&v,&c);
up=max(up,c);
add(u,v,c);
}
return up;
} bool BF(int st,int n)
{
clr(inq,);
clr(cnt,);
queue<int>q;
rep(i,,n){
if(i==st)d[i]=;
else d[i]=INF;
q.push(i);
}
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=false;
int sz=G[u].size();
rep(i,,sz-){
Edge e=edge[G[u][i]];
if(d[e.v]>d[u]+e.c){
d[e.v]=d[u]+e.c;
if(!inq[e.v]){
q.push(e.v);
inq[e.v]=true;
if(++cnt[e.v]>n)
return true;
}
}
}
}
return false;
} bool test(int n,int m,int x)
{
rep(i,,m-)
edge[i].c-=x;
bool flog=BF(,n);
rep(i,,m-)
edge[i].c+=x;
return flog;
} int main()
{
int T,n,m;
while(~scanf("%d%d",&n,&m))
{
init(n);
int up=build(m); if(!test(n,m,up+))
printf("Infinite\n");
else if(test(n,m,))
printf("No Solution\n");
else{
int l=,r=up;
while(l<r)
{
int x=l+(r-l+)/;
if(test(n,m,x))
r=x-;
else
l=x;
}
printf("%d\n",l);
}
}
return ;
}

后记:

1、书上所说“最短路中的不等式d[v]<=d[u]+w(u,v)”指的是最短路的关系式,而不是松弛操作。表示从起点s->v的最短路恒<=s->u的最短路+w(u,v)。

2、根据不等式的变形,的确可以自由选择使用最长路还是最短路求解,但两种方法所得的答案不同,具体解释http://www.cnblogs.com/zstu-abc/p/3277305.html

UVA 11478 Halum(用bellman-ford解差分约束)的更多相关文章

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

    layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catal ...

  2. 【UVA11478】Halum (最短路解差分约束)

    题目: Sample Input2 11 2 102 11 2 -103 31 2 42 3 23 1 54 52 3 44 2 53 4 23 1 01 2 -1Sample OutputInfin ...

  3. UVA - 11478 - Halum(二分+差分约束系统)

    Problem  UVA - 11478 - Halum Time Limit: 3000 mSec Problem Description You are given a directed grap ...

  4. UVA 11478 Halum

    Halum Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 114 ...

  5. UVA 11478 Halum (差分约束)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  6. UVA 11478 Halum(差分约束)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34651 [思路] 差分约束系统. 设结点u上的操作和为sum[u] ...

  7. UVA - 11478 Halum 二分+差分约束

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34651 题意: 给定一个有向图,每一条边都有一个权值,每次你可以 ...

  8. Uva 11478 Halum操作

    题目链接:http://vjudge.net/contest/143318#problem/B 题意:给定一个有向图,每条边都有一个权值.每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权 ...

  9. 【POJ1021】Intervals (最短路解差分约束)

    题目: Sample Input 5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1 Sample Output 6 题意: 我们选数,每个数只能选一次.给定n个条件[ai,bi]和 ...

随机推荐

  1. 2064: 分裂 - BZOJ

    Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的他把这个变成了一个数学模型. 假设中 ...

  2. c++ 原子操作

    转载自: http://blog.csdn.net/yockie/article/details/8838686 所谓的原子操作,取的就是“原子是最小的.不可分割的最小个体”的意义,它表示在多个线程访 ...

  3. WEB前端常用的测试工具

    一.QUnit 前端测试工具 QUnit是一个强大的JavaScript单元测试框架,该框架是由jQuery团队的成员所开发,并且是jQuery的官方测试套件.Qunit是Jquery的单元测试框架, ...

  4. NYOJ-44 子串和 AC 分类: NYOJ 2014-01-04 22:53 154人阅读 评论(0) 收藏

    作为菜鸟一枚,对子串和的代码完全就是硬算 的..结果是TLE #include<stdio.h> int jh(int x,int y,int num[],int sum[]); int ...

  5. EBP的妙用[无法使用ESP定律时]

    1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...

  6. 字符串匹配--kmp算法原理整理

    kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...

  7. hdu 4599 Dice 概率DP

    思路: 1.求f[n];dp[i]表示i个连续相同时的期望 则 dp[0]=1+dp[1]     dp[1]=1+(5dp[1]+dp[2])/6     ……     dp[i]=1+(5dp[1 ...

  8. hdu 4335 What is N?

    此题用到的公式:a^b%c=a^(b%phi(c)+phi(c))%c (b>=phi(c)). 1.当n!<phi(p)时,直接暴力掉: 2.当n!>=phi(p) &&a ...

  9. C Primer Plus 第5章 运算符、表达式和语句 编程练习

    1. #include <stdio.h> ; int main(void) { int min, hour, lmin; printf("请输入分钟数: \n"); ...

  10. .NET framework 4.0安装失败怎么办

    开始——运行——输入cmd——回车——在打开的窗口中输入net stop WuAuServ   开始——运行——输入%windir%找到有个叫SoftwareDistribution的文件夹,把它重命 ...