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

题目:

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

题意:

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

分析:

  因为不同的操作互不影响,因此可以按任意顺序实施这些操作。另外,对于同一个点的多次操作可以合并,因此可以令sum(u)为作用于结点u之上的所有d之和。这样,本题的目标就是确定所有的sum(u),使得操作之后所有边权的最小值尽量大。

  “最小值最大”又让我们想到使用二分答案的方法。二分答案x之后,问题转化为是否可以让操作完毕后每条边的权值均不小于x。对于边a->b,不难发现操作完毕后它的权值为w(a,b)+sum(a)-sum(b),因此每条边a->b都可以列出一个不等式w(a,b)+sum(a)-sum(b)>=x,移项得sum(b)-sum(a)<=w(a,b)-x。这样,我们实际得到一个差分约束系统。

  差分约束系统是指一个不等式组,每个不等式形如xj-xi<=bk,这里的bk是一些事先已知的常数。这个不等式类似于最短路中的不等式d[v]<=d[u]+w(u,v),我们可以用最短路算法求解:对于约束条件xj-xi<=bk,新建一条边i->j,(根据最短路性质可以证明在图无负环的情况下这个不等式是成立的)权值为bk。如果图中有负权环,则差分约束系统无解。

代码如下:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<queue>
  7 using namespace std;
  8 #define Maxn 510
  9 #define Maxm 4010
 10 #define INF 0xfffffff
 11
 12 int n,m;
 13 int first[Maxn],dis[Maxn],cnt[Maxn];
 14 bool bq[Maxn],inq[Maxn];
 15
 16 struct node
 17 {
 18     int x,y,c,cc,next;
 19 }t[Maxm];int len;
 20
 21 int mymax(int x,int y) {return x>y?x:y;}
 22
 23 void ins(int x,int y,int cc)
 24 {
 25     t[++len].x=x;t[len].y=y;t[len].cc=cc;
 26     t[len].next=first[x];first[x]=len;
 27 }
 28
 29 queue<int > q;
 30
 31 bool spfa(int s)
 32 {
 33     memset(inq,0,sizeof(inq));
 34     memset(dis,63,sizeof(dis));
 35     memset(cnt,0,sizeof(cnt));
 36     while(!q.empty()) q.pop();
 37     dis[s]=0;inq[s]=1;q.push(s);
 38     while(!q.empty())
 39     {
 40         int x=q.front();q.pop();inq[x]=0;
 41         for(int i=first[x];i;i=t[i].next)
 42         {
 43             int y=t[i].y;
 44             if(dis[y]>dis[x]+t[i].c)
 45             {
 46                 dis[y]=dis[x]+t[i].c;
 47                 if(!inq[y])
 48                 {
 49                     q.push(y);
 50                     inq[y]=1;
 51                     if(++cnt[y]>n+1) return 1;
 52                 }
 53             }
 54         }
 55     }
 56     return 0;
 57 }
 58
 59 bool check(int x)
 60 {
 61     memset(bq,0,sizeof(bq));
 62     for(int i=1;i<=len-n;i++) t[i].c=t[i].cc-x;
 63     if(spfa(n+1)) return 0;
 64     /*for(int i=1;i<=n+1;i++) if(!bq[i])
 65     {
 66         if(spfa(i)) return 0;
 67     }*/
 68     return 1;
 69 }
 70
 71 void ffind(int l,int r)
 72 {
 73     while(l<r)
 74     {
 75         int mid=(l+r+1)>>1;
 76         if(check(mid)) l=mid;
 77         else r=mid-1;
 78     }
 79     printf("%d\n",l);
 80 }
 81
 82 int main()
 83 {
 84     while(scanf("%d%d",&n,&m)!=EOF)
 85     {
 86         memset(first,0,sizeof(first));
 87         int mx=-INF;len=0;
 88         for(int i=1;i<=m;i++)
 89         {
 90             int x,y,cc;
 91             scanf("%d%d%d",&x,&y,&cc);
 92             ins(x,y,cc);
 93             mx=mymax(cc,mx);
 94         }
 95         for(int i=1;i<=n;i++)
 96         {
 97             ins(n+1,i,0);t[len].c=0;
 98         }
 99         if(check(mx+1)) {printf("Infinite\n");continue;}
100         if(!check(1)) {printf("No Solution\n");continue;}
101         ffind(1,mx);
102     }
103     return 0;
104 }

[UVA11478]

2016-04-10 15:33:20

时间: 2024-10-12 20:58:33

【UVA11478】Halum (最短路解差分约束)的相关文章

poj3169 最短路(差分约束)

题意:一个农夫有n头牛,他希望将这些牛按照编号 1-n排成一条直线,允许有几头牛站在同一点,但是必须按照顺序,有一些牛关系比较好,希望站的距离不超过某个值,而有一些牛关系不太好,所以希望站的距离大于等于某个值,问1号牛和n号牛之间的最远距离是多少. 差分约束的裸题,对于 d[v] - d[u] ≤ w 建立权值为 w 的单向边 e(u,v),对于 d[v] - d[u]  ≥ w 建立权值为 -w 的单向边 e(v,u),然后再根据牛必须按顺序排列建立权值为 0 的边 e(i+1,i),然后最短

poj3159 最短路(差分约束)

题意:现在需要分糖果,有n个人,现在有些人觉得某个人的糖果数不能比自己多多少个,然后问n最多能在让所有人都满意的情况下比1多多少个. 这道题其实就是差分约束题目,根据题中给出的 a 认为 b 不能比 a 多 c 个,也就是 d[b] - d[a] ≤ c,就可以建立 value 值为 c 的单向边 e(a,b) ,然后先定d[1] = 0 ,用最短路跑完得到的 d[n] 就是所求答案. 1 #include<stdio.h> 2 #include<string.h> 3 #incl

POJ 2983 Is the Information Reliable? 信息可靠吗 (差分约束,spfa)

题意:有n个站排成一列,针对每个站的位置与距离关系,现有多个约束条件,约束条件分两种:(1)确定的.明确说明站a距离站b多少个单位距离.(2)不确定的.只知道a在b的左边至少1个单位距离.  根据已知条件,问有没有冲突?不冲突则输出reliable. 思路: 第2种条件比较好确定,如果知道如何用最短路解差分约束的话. 问题在第1种,明确地说明了距离,怎么办?拆成两条式子,比如 dis(a,b)=c,那么可以写成 b-a>=c ,b-a<=c 这样,只要满足这两个条件,原来明确说明的距离也会成立

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)

UVA11478 Halum (差分约束)

每次操作是独立的,而且顺序并不影响,作用在同一个结点上的d可以叠加,所以令x(u) = sigma(dui). 最后就是要确定所有的x(u). 因为m越大,满足条件的边就越少,二分答案m. 对于一条边a->b,可以列出一个不等式d(a,b) +x(a)-x(b)>=m,移项可得x(b)-x(a)<=d(a,b)-m 正好满足差分约束的形式.所有的边就对应着一个差分约束系统. 差分约束有解的充要条件是不存在负环. 证明: x(b)-x(a)<=-c,c>0,意味着x(a)至少比

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

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

K - Candies(最短路+差分约束)

题目大意:给N个小屁孩分糖果,每个小屁孩都有一个期望,比如A最多比B多C个,再多了就不行了,会打架的,求N最多比1多几块糖 分析:就是求一个极小极大值...试试看 这里需要用到一个查分约束的东西 下面是查分约束详解: 一直不知道差分约束是什么类型题目,最近在写最短路问题就顺带看了下,原来就是给出一些形如x-y<=b不等式的约束,问你是否满足有解的问题 好神奇的是这类问题竟然可以转换成图论里的最短路径问题,下面开始详细介绍下 比如给出三个不等式,b-a<=k1,c-b<=k2,c-a<

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)