题目链接:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34651

题意:

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

题解:

最小值最大,可以用二分,这样可以得到一个差分约束系统,然后每次都用最短路跑。

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<vector>
  5. #include<queue>
  6. #include<algorithm>
  7. using namespace std;
  8.  
  9. const int maxn = ;
  10. const int maxm = ;
  11.  
  12. struct Edge {
  13. int v, w;
  14. Edge(int v, int w) :v(v), w(w) {}
  15. Edge() {}
  16. };
  17.  
  18. vector<Edge> egs;
  19. vector<int> G[maxn];
  20. int tot = ;
  21. int n, m;
  22.  
  23. void addEdge(int u, int v, int w) {
  24. egs.push_back(Edge(v, w));
  25. tot = egs.size();
  26. G[u].push_back(tot - );
  27. }
  28.  
  29. bool inq[maxn];
  30. int d[maxn];
  31. int cnt[maxn];
  32. bool spfa(int x) {
  33. bool ret = true;
  34.  
  35. for (int i = ; i < n; i++) {
  36. for (int j = ; j < G[i].size(); j++) {
  37. Edge& e = egs[G[i][j]];
  38. e.w -= x;
  39. }
  40. }
  41. memset(inq, , sizeof(inq));
  42. memset(cnt, , sizeof(cnt));
  43. memset(d, 0x3f, sizeof(d));
  44.  
  45. queue<int> Q;
  46. d[] = ; inq[] = true; Q.push();
  47. while (!Q.empty()) {
  48. int u = Q.front(); Q.pop();
  49. inq[u] = false;
  50. for (int i = ; i < G[u].size(); i++) {
  51. Edge& e = egs[G[u][i]];
  52. if (d[e.v] > d[u] + e.w) {
  53. d[e.v] = d[u] + e.w;
  54. if (!inq[e.v]) {
  55. Q.push(e.v); inq[e.v] = true;
  56. if (++cnt[e.v] > n) {
  57. ret = false; break;
  58. }
  59. }
  60. }
  61. }
  62. if (ret == false) break;
  63. //printf("u:%d\nx:%d\n", u,x);
  64. //printf("in circle\n");
  65. }
  66.  
  67. for (int i = ; i < n; i++) {
  68. for (int j = ; j < G[i].size(); j++) {
  69. Edge& e = egs[G[i][j]];
  70. e.w += x;
  71. }
  72. }
  73.  
  74. return ret;
  75. }
  76.  
  77. void init() {
  78. for (int i = ; i < n; i++) G[i].clear();
  79. egs.clear();
  80. }
  81.  
  82. int main() {
  83. while (scanf("%d%d", &n, &m) == && n) {
  84. n++;
  85. init();
  86. int l = , r = -;
  87. for (int i = ; i < m; i++) {
  88. int u, v, w;
  89. scanf("%d%d%d", &u, &v, &w);
  90. r = max(r, w);
  91. addEdge(u, v, w);
  92. }
  93. for (int i = ; i < n; i++) {
  94. addEdge(, i, );
  95. }
  96. r++;
  97. if (!spfa()) {
  98. printf("No Solution\n");
  99. }
  100. else if (spfa(r)) {
  101. printf("Infinite\n");
  102. }
  103. else {
  104. while (l + < r) {
  105. int mid = l + (r - l) / ;
  106. if (spfa(mid)) l = mid;
  107. else r = mid;
  108. //printf("here!\n");
  109. }
  110. printf("%d\n", l);
  111. }
  112.  
  113. }
  114. return ;
  115. }
  116.  
  117. /*
  118. 1
  119. 2 10
  120. 1
  121. 2 -10
  122. 3
  123. 2 4
  124. 3 2
  125. 1 5
  126. 5
  127. 3 4
  128. 2 5
  129. 4 2
  130. 1 0
  131. 2 -1
  132. */

UVA - 11478 Halum 二分+差分约束的更多相关文章

  1. UVA 11478 Halum(差分约束)

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

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

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

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

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

  4. UVA 11478 Halum(用bellman-ford解差分约束)

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

  5. UVA 11478 Halum

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

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

    题目链接 POJ1275 题解 显然可以差分约束 我们记\(W[i]\)为\(i\)时刻可以开始工作的人数 令\(s[i]\)为前\(i\)个时刻开始工作的人数的前缀和 每个时刻的要求\(r[i]\) ...

  7. UVA11478 Halum (差分约束)

    每次操作是独立的,而且顺序并不影响,作用在同一个结点上的d可以叠加,所以令x(u) = sigma(dui). 最后就是要确定所有的x(u). 因为m越大,满足条件的边就越少,二分答案m. 对于一条边 ...

  8. UVA 11478 Halum (差分约束)

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

  9. Uva 11478 Halum操作

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

随机推荐

  1. sublime text2支持ng

    这里面记录了sublime text3的一些破解和sublime text2支持ng的方法. http://weblogs.asp.net/dwahlin/archive/2013/08/30/usi ...

  2. Windows 和  Linux 下 禁止ping的方法

    Windows 和Linux 下 禁止ping的方法 目的: 禁止网络上的其他主机或服务器ping自己的服务器 运行环境: Windows 03.08  linux 方法: Windows 03下: ...

  3. C#winform导出数据到Excel的类

    /// <summary> /// 构造函数 /// </summary> public ExportData() { } /// <summary> /// 保存 ...

  4. phpmyadmin误删表后的恢复过程(心惊胆跳啊)

    话说今天不知道是抽风了还是失魂了,在用phpmyadmin删除测试数据时,竟然将整个表删除了: 等程序运行出错时,才出现整个表都没有了,而且之前也没有备份好!这下蛋疼了,这个可是production服 ...

  5. VB 进制转换大全

    '二进制转十进制 Public Function B2D(vBStr As String) As Long Dim vLen As Integer '串长 Dim vDec As Long '结果 D ...

  6. 文件系统 第八次迭代 VFS相关说明

    麻烦访问evernote链接 http://www.evernote.com/shard/s133/sh/53e5b5ac-1192-4910-8bd5-6886218562af/59516c32a5 ...

  7. 菜鸟学习Spring——60s让你学会动态代理原理

    一.为什么要使用动态代理         当一个对象或多个对象实现了N中方法的时候,由于业务需求需要把这个对象和多个对象的N个方法加入一个共同的方法,比如把所有对象的所有方法加入事务这个时候有三种方法 ...

  8. SpringMvc中Interceptor拦截器用法

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆等. 一. 使用场景 1 ...

  9. css权重及优先级问题

    css权重及优先级问题 几个值的对比 初始值 指定值 计算值 应用值 CSS属性的 指定值 (specified value)会通过下面3种途径取得: 在当前文档的样式表中给这个属性赋的值,会被优先使 ...

  10. C++ STL vector 内存分配

    vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储. 当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间.拷贝元素.撤销 ...