差分约束系统的第一个题目,看了落花大神的博客后,对差分约束有了一定了解,关键在于建图,然后就是判断是否存在负权回路。

关于差分约束系统的解释详见维基百科:http://zh.wikipedia.org/wiki/%E5%B7%AE%E5%88%86%E7%BA%A6%E6%9D%9F%E7%B3%BB%E7%BB%9F

利用spfa判断时,当图中有顶点出队次数多于图中顶点数目时说明存在负环。

其实我自己敲上去的时候改了一点点。

大神的time[g[x][i].v]当达到n+1时就返回false,这是不对的,因为点包括0嘛,所以最终应该有n+1个点,判断就应该改为达到n+2,而且这一点也从uva上得到证明,

直接交n+1的版本是过不了的,n+2,才能过。

以下是我改过大神的代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. #include <cstdlib>
  5. #include <vector>
  6. #define N 110
  7. using namespace std;
  8.  
  9. struct edgeType{
  10. int v, w;
  11. edgeType(int a, int b):v(a), w(b){}
  12. };
  13. int n, m, d[N], time[N], inq[N];
  14. char op[];
  15.  
  16. vector<edgeType> g[N];
  17. bool spfa(void)
  18. {
  19. queue<int> q;
  20. time[n] = ;
  21. inq[n] = ;
  22. q.push(n);
  23. while(!q.empty())
  24. {
  25. int x = q.front();
  26. q.pop();
  27. inq[x] = ;
  28. for(int i = ; i < g[x].size(); i++)
  29. if(d[g[x][i].v] > d[x] + g[x][i].w)
  30. {
  31. d[g[x][i].v] = d[x] + g[x][i].w;
  32. time[g[x][i].v]++;
  33. if(time[g[x][i].v] == n+)
  34. return false;
  35. if(!inq[g[x][i].v])
  36. {
  37. q.push(g[x][i].v);
  38. inq[g[x][i].v] = ;
  39. }
  40. }
  41. }
  42. return true;
  43. }
  44.  
  45. int main(void)
  46. {
  47. int a, b, c;
  48. while(scanf("%d%d",&n, &m)&&n)
  49. {
  50. n++;
  51. memset(d, 0x0f, sizeof(d));
  52. memset(inq, , sizeof(inq));
  53. memset(time, , sizeof(time));
  54. d[n] = ;
  55. g[n].clear();
  56. for(int i = ; i < n;i++)
  57. g[n].push_back(edgeType(i, )), g[i].clear();
  58. for(int i = ; i < m; i++)
  59. {
  60. scanf("%d%d%s%d", &a, &b, op, &c);
  61. if(op[] == 'g')
  62. g[a + b].push_back(edgeType(a - , -c - ));
  63. else g[a - ].push_back(edgeType(a + b, c - ));
  64. }
  65. if(spfa())
  66. puts("lamentable kingdom");
  67. else puts("successful conspiracy");
  68. }
  69. return ;
  70. }

然后我利用bellman—ford重新写了一遍,速度慢了将近一半,不知道是不是我写的姿势不对。

来自维基百科的bellman-ford的伪代码:

  1. # initialization
  2. for each v in V do
  3. d[v] ∞;
  4. d[source] 0
  5. # Relaxation
  6. for i =1,...,|V|-1 do
  7. for each edge (u,v) in E do
  8. d[v] min{d[v], d[u]+w(u,v)}
  9. # Negative cycle checking
  10. for each edge (u, v) in E do
  11. if d[v]> d[u] + w(u,v) then
  12. no solution

其实就是普通bellman-ford做完之后,再检查所有的边一次,看看能不能继续松弛,如果可以的话,松弛变数会超过:|V|-1,说明必须存在负权环。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. #include <cstdlib>
  5. #include <vector>
  6. #define N 110
  7. using namespace std;
  8.  
  9. struct edgeType
  10. {
  11. int v, w;
  12. edgeType(int a, int b):v(a), w(b) {}
  13. };
  14. int n, m, d[N], inq[N];
  15. char op[];
  16. vector<edgeType> g[N];
  17.  
  18. bool bellman_ford(void)
  19. {
  20. for(int k = ; k < n; k++)
  21. for(int x = ; x <= n; x++)
  22. for(int i = ; i < (int)g[x].size(); i++)
  23. if(d[g[x][i].v] > d[x] + g[x][i].w)
  24. d[g[x][i].v] = d[x] + g[x][i].w;
  25. for(int i = ; i <= n; i++)
  26. {
  27. for(int k = ; k < (int)g[i].size(); k++)
  28. if(d[g[i][k].v] > d[i] + g[i][k].w)
  29. return false;
  30. }
  31. return true;
  32. }
  33.  
  34. int main(void)
  35. {
  36. int a, b, c;
  37. while(scanf("%d",&n)&&n)
  38. {
  39. n++;
  40. scanf("%d", &m);
  41. memset(d, 0x0f, sizeof(d));
  42. memset(inq, , sizeof(inq));
  43. d[n] = ;
  44. g[n].clear();
  45. for(int i = ; i < n; i++)
  46. g[n].push_back(edgeType(i, )), g[i].clear();
  47. for(int i = ; i < m; i++)
  48. {
  49. scanf("%d%d%s%d", &a, &b, op, &c);
  50. if(op[] == 'g')
  51. g[a + b].push_back(edgeType(a - , -c - ));
  52. else g[a - ].push_back(edgeType(a + b, c - ));
  53. }
  54. if(bellman_ford())
  55. puts("lamentable kingdom");
  56. else puts("successful conspiracy");
  57. }
  58. return ;
  59. }

UVA 515 King的更多相关文章

  1. POJ 1364 King (UVA 515) 差分约束

    http://poj.org/problem?id=1364 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemi ...

  2. UVA 515 差分约束 SPFA判负

    第一次看这个题目,完全不知道怎么做,看起来又像是可以建个图进行搜索,但题目条件就给了你几个不等式,这是怎么个做法...之后google了下才知道还有个差分约束这样的东西,能够把不等式化成图,要求某个点 ...

  3. UVA题目分类

    题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...

  4. UVa 109 - SCUD Busters(凸包计算)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  5. UVA它11292 - Dragon of Loowater

    Problem C: The Dragon of Loowater Once upon a time, in the Kingdom of Loowater, a minor nuisance tur ...

  6. UVA 11292 Dragon of Loowater(简单贪心)

    Problem C: The Dragon of Loowater Once upon a time, in the Kingdom of Loowater, a minor nuisance tur ...

  7. HDU 5643 King's Game 打表

    King's Game 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5643 Description In order to remember hi ...

  8. cogs 1405. 中古世界的恶龙[The Drangon of Loowater,UVa 11292]

    1405. 中古世界的恶龙[The Drangon of Loowater,UVa 11292] ★   输入文件:DragonUVa.in   输出文件:DragonUVa.out   简单对比时间 ...

  9. UVA1327 && POJ1904 King's Quest(tarjan+巧妙建图+强连通分量+缩点)

    UVA1327 King's Quest POJ1904 King's Quest 题意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚.现有一个匹配表,将每个王子都与一个自己 ...

随机推荐

  1. Exchanger, Changing data between concurrent tasks

    The Java concurrency API provides a synchronization utility that allows the interchange of data betw ...

  2. c#调用c++ dll(二)

    当对c++几种调用方式有了解以后我们可以试着写个c++动态连接库了,我们现在来写个简单的c++求和函数并把它封装成dll,供以后的c#调用 我们写dll的时候,个人认为,要写就要把dll写好,写标准, ...

  3. jsp页面在IE8下文本模式自动为“杂项(Quirks)”导致页面显示错位

    最近在修改网站的响应式的页面时,由于都是套样式页面,修改过程都是粘贴复制,导致了一些细节问题在IE8下暴露出来: 遇到的问题就是在在Chrome,火狐页面都正常,唯独在IE8下页面样式显示乱样了,但是 ...

  4. 第十二篇、高度自适应的textView

    高度根据输入内容变化输入框,我们在很多的应用上都可以见到,如微信.QQ聊天,QQ空间评论等等,该输入框可以用xib,纯代码编写,但是个人觉得纯代码编写用起来更加方便一些. 1.使用自定义的UIView ...

  5. 12天学好C语言——记录我的C语言学习之路(Day 3)

    12天学好C语言--记录我的C语言学习之路 Day 3: 不知不觉到了第三天的学习,我们前两天学习的东西很杂乱,各个方面都有学习.我觉得这不是不系统,也不是学的不扎实,这种学习对于初学者而言我认为是很 ...

  6. android 登陆案例_最终版本 sharedpreference

    xml  与之前的登陆案例相同 java代码: package com.itheima.login; import java.util.Map; import com.itheima.login.ut ...

  7. 第一个 MIC shared_memory 程序

    设置Intel编译器的运行环境 在terminal中执行编译器的环境脚本 compilervars.sh: source <install-dir>/bin/compilervars.sh ...

  8. OpenJudge/Poj 1316 Self Numbers

    1.链接地址: http://poj.org/problem?id=1316 http://bailian.openjudge.cn/practice/1316 2.题目: 总时间限制: 1000ms ...

  9. SVN查看提交日志的命令

    Windows下,使用svn客户端查看日志很方便,但是如果在linux下,常规查看日志的命令对于日志记录数比较多的时候,屏幕显示不了,就比较麻烦,后来发现了一个很有用的参数可以限制要查看的记录条数 查 ...

  10. .NET小项目之MyKtv(歌曲播放功能实现)

    在KTV点歌系统中我们根据需求获取到歌手的歌曲信息,点击歌手的歌曲将其添加到一点歌曲列表中看似简单的一个操作其实涉及很多内容,这也是写这篇Blog的目的—分析歌曲播放的原理. 原理分析 我们应该清楚, ...