这是通化邀请赛的题,当时比赛的时候还完全没想法呢,看来这几个月的训练还是有效果的。。。

题意要求(1) |ai| < T for all i   (2) (vi, vj) in E <=> |ai - aj| >= T。由于(1)条件的存在,所以(2)条件能成立当且仅当ai和aj一正一负。由此可见,图中某条路上的元素正负值分别为正->负->正->负。。。显然当图中存在奇环的时候是无解的。判断奇环用二分染色,color[i]=0表示假设i节点未被染色,1表示假设i节点权值为正,2为负。

如果图中没有奇环呢?对于图中的一条边<u, v>,如果color[u]=1,那么显然a[u]-a[v] >= T,color[u]=2, 也就是 -(a[u]-a[v]) >= T;

而如果<u, v>不是图中的边, 必然有 | a[u]-a[v] |  < T。由color数组也同样能得到两个不等式。

得到不等式组后无脑跑spfa判负环就行了。。。光是判负环的spfa是不用考虑加入0节点的,在初始化得时候将每个节点加到队列一次就够了。而且d数组也完全可以初始化为0。因为你只需要判负环而已。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<fstream>
  6. #include<sstream>
  7. #include<vector>
  8. #include<string>
  9. #include<cstdio>
  10. #include<bitset>
  11. #include<stack>
  12. #include<queue>
  13. #include<cmath>
  14. #include<map>
  15. #include<set>
  16. #define FF(i, a, b) for(int i=a; i<b; i++)
  17. #define FD(i, a, b) for(int i=a; i>=b; i--)
  18. #define REP(i, n) for(int i=0; i<n; i++)
  19. #define CLR(a, b) memset(a, b, sizeof(a))
  20. #define PB push_back
  21. #define LL long long
  22. #define eps 1e-10
  23. #define debug puts("**debug**")
  24. using namespace std;
  25.  
  26. const int maxn = 333;
  27. const int T = 1000;
  28. struct Edge
  29. {
  30. int from, to, dist;
  31. };
  32. vector<Edge> edges;
  33. vector<int> G[maxn];
  34. vector<int> g[maxn];
  35. int n, ncase, color[maxn], flag, d[maxn], cnt[maxn];
  36. bool inq[maxn];
  37. char ch[maxn][maxn];
  38.  
  39. void init()
  40. {
  41. REP(i, n) G[i].clear(), g[i].clear();
  42. edges.clear(); CLR(color, 0);
  43. }
  44.  
  45. void add(int a, int b, int c)
  46. {
  47. edges.PB((Edge){a, b, c});
  48. int nc = edges.size();
  49. G[a].PB(nc-1);
  50. }
  51.  
  52. void dfs(int u, int c) //二分染色
  53. {
  54. color[u] = c;
  55. int nc = g[u].size();
  56. REP(i, nc)
  57. {
  58. int v = g[u][i];
  59. if(!color[v]) dfs(v, 3-c);
  60. }
  61. }
  62.  
  63. bool spfa()
  64. {
  65. queue<int> q;
  66. REP(i, n) d[i] = cnt[i] = 0, inq[i] = 1, q.push(i);
  67. while(!q.empty())
  68. {
  69. int u = q.front(); q.pop();
  70. inq[u] = false;
  71. REP(i, G[u].size())
  72. {
  73. Edge& e = edges[G[u][i]];
  74. if(d[e.to] > d[u] + e.dist)
  75. {
  76. d[e.to] = d[u] + e.dist;
  77. if(!inq[e.to])
  78. {
  79. q.push(e.to);
  80. inq[e.to] = true;
  81. if(++cnt[e.to] > n) return true;
  82. }
  83. }
  84. }
  85. }
  86. return false;
  87. }
  88.  
  89. bool solve()
  90. {
  91. //判奇圈
  92. REP(i, n) if(!color[i]) dfs(i, 1);
  93. REP(i, n) REP(j, g[i].size()) if(color[i] == color[g[i][j]]) return 0;
  94.  
  95. REP(i, n)
  96. {
  97. FF(j, i+1, n)
  98. {
  99. if(ch[i][j] == '1')
  100. {
  101. if(color[i] == 1) add(i, j, -T);
  102. else add(j, i, -T);
  103. }
  104. else
  105. {
  106. if(color[i] == 1) add(j, i, T-1);
  107. else add(i, j, T-1);
  108. }
  109. }
  110. }
  111. if(spfa()) return 0;
  112. return 1;
  113. }
  114.  
  115. int main()
  116. {
  117. scanf("%d", &ncase);
  118. while(ncase--)
  119. {
  120. init();
  121. scanf("%d", &n);
  122. REP(i, n)
  123. {
  124. scanf("%s", ch[i]);
  125. REP(j, n) if(i != j && ch[i][j] == '1') g[i].PB(j);
  126. }
  127. if(solve()) puts("Yes");
  128. else puts("No");
  129. }
  130. return 0;
  131. }

hdu 4598 Difference(奇圈判定+差分约束)的更多相关文章

  1. HDU 4598 Difference

    Difference Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...

  2. HDU 3666 THE MATRIX PROBLEM (差分约束 深搜 & 广搜)

    THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. HDU 3666 THE MATRIX PROBLEM (差分约束,最短路)

    题意: 给一个n*m矩阵,每个格子上有一个数字a[i][j],给定L和U,问:是否有这样两个序列{a1...an}和{b1...bn},满足 L<=a[i][j]*ai/bj<=U .若存 ...

  4. HDU 3592 World Exhibition(线性差分约束,spfa跑最短路+判断负环)

    World Exhibition Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. hdu 4598 差分约束

    思路:首先就是判断是否有奇环,若存在奇环,则输出No. 然后用差分约束找是否符合条件. 对于e(i,j)属于E,并且假设顶点v[i]为正数,那么v[i]-v[j]>=T--->v[j]-v ...

  6. HDU 3118 Arbiter 判定奇圈

    题目来源:pid=3118">HDU 3118 Arbiter 题意:翻译过来就是不能有奇圈 每走一步状态会变化 当他回到起点时假设和原来的状态不一样 可能会死 求至少去掉多少条边能够 ...

  7. hdu 1531(差分约束)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1531 差分约束的题之前也碰到过,刚好最近正在进行图论专题的训练,就拿来做一做. ①:对于差分不等式,a ...

  8. POJ 1364 / HDU 3666 【差分约束-SPFA】

    POJ 1364 题解:最短路式子:d[v]<=d[u]+w 式子1:sum[a+b+1]−sum[a]>c      —      sum[a]<=sum[a+b+1]−c−1  ...

  9. POJ 3169 Layout (HDU 3592) 差分约束

    http://poj.org/problem?id=3169 http://acm.hdu.edu.cn/showproblem.php?pid=3592 题目大意: 一些母牛按序号排成一条直线.有两 ...

随机推荐

  1. php数字转中文

    function number2Chinese($num, $m = 1) { switch($m) { case 0: $CNum = array( array('零','壹','贰','叁','肆 ...

  2. Python成长之路第一篇(3)_初识字典

    经过上章的学习我们已经了解到了列表可以通过索引来获取对应的值,在本章我们将学到通过名字来索引数据,这种结构的类型称之为映射(maooing),在Python中字典是唯一内建的映射类型,其中的值我们称之 ...

  3. *循环-01. 求整数段和【help】

    /* * Main.c * 循环-01. 求整数段和 * Created on: 2014年6月18日 * Author: Boomkeeper ***测试木有通过**** */ #include & ...

  4. c/c++与java------之JNI学习(一)

    一.java 调用c/c++ 步骤: 1.在java类中创建一个native关键字声明的函数 2.使用javah生成对应的.h文件 3.在c/c++中实现对应的方法 4.使用vs2012创建一个win ...

  5. json、map互转

    首先,json转map 方法一: Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 或 Gs ...

  6. SVG关注复杂图形的网页绘制技术

    SVG 是使用 XML 来描述二维图形和绘图程序的语言. 学习之前应具备的基础知识: 继续学习之前,你应该对以下内容有基本的了解: HTML XML 基础 如果希望首先学习这些内容,请在本站的首页选择 ...

  7. JenKins 环境搭建 for Centos6.5

    1,JenKines简单介绍--图解

  8. MySQL- 锁机制及MyISAM表锁

    锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许 多用户 共享的资源.如何保证数据并发访问的一致性.有效性是所 ...

  9. iOS常用的封装方法

    做开发也有一段时间了,看了好多大神的代码,总体感觉他们写的代码简洁,好看,然而在对比下我写的代码,混乱,无序,简直不堪入目啊! 总体来说大神们的代码封装的都比较好,对一个项目要重复用到的代码他们都会封 ...

  10. 自适应Cell

        // //  ViewController.m //  04-自适应cell // //  Created by