题目链接

题意是说在几个邮局之间传送一份信件,如果出发点和终止点在同一个国家传递,则时间为0,否则让你求花费最少时间,如果不能传到,则输出Nao e possivel entregar a carta。判断邮局是否在同一个国家的依据是发出的信件可以相互到达。
如果直接求最短路则无法判断两个邮局是否在同一个国家,判断两个邮局是否属于同一个国家的标志是在这个国家邮局间可以相互到达,那么这就是强连通了,所以要先缩点判读邮局是否在同一个国家,如果不是,则重新建图,建图的时候要维护好边权,求出最短边权,在用dijkstra求出最短路即可。
  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <vector>
  6. using namespace std;
  7. const int Max = ;
  8. const int INF = 0x3f3f3f3f;
  9. int n, m, dfs_clock, scc_cnt, scnt;
  10. int g[Max][Max], pre[Max], low[Max], Stack[Max], sccno[Max];
  11. int G[Max][Max];
  12. int head[Max], num;
  13. struct Edge
  14. {
  15. int v, Next;
  16. };
  17. Edge edge[Max * Max];
  18. void addEdge(int u, int v)
  19. {
  20. edge[num].v = v;
  21. edge[num].Next = head[u];
  22. head[u] = num++;
  23. }
  24. void init()
  25. {
  26. memset(head, -, sizeof(head));
  27. memset(pre, , sizeof(pre));
  28. //memset(low, 0, sizeof(low));
  29. memset(sccno, , sizeof(sccno));
  30. scnt = dfs_clock = scc_cnt = num = ;
  31. for (int i = ; i <= n; i++)
  32. for (int j = i; j <= n; j++)
  33. {
  34. if (i == j)
  35. G[i][j] = g[i][j] = ;
  36. else
  37. {
  38. g[i][j] = g[j][i] = INF;
  39. G[i][j] = G[j][i] = INF;
  40. }
  41. }
  42. }
  43. void dfs(int u)
  44. {
  45. pre[u] = low[u] = ++dfs_clock;
  46. Stack[scnt++] = u;
  47. for (int i = head[u]; i != -; i = edge[i].Next)
  48. {
  49. int v = edge[i].v;
  50. if (!pre[v])
  51. {
  52. dfs(v);
  53. low[u] = min(low[u], low[v]);
  54. }
  55. else if (!sccno[v])
  56. low[u] = min(low[u], pre[v]);
  57. }
  58. if (low[u] == pre[u])
  59. {
  60. scc_cnt++;
  61. for (; ;)
  62. {
  63. int x = Stack[--scnt];
  64. sccno[x] = scc_cnt;
  65. if ( x == u)
  66. break;
  67. }
  68. }
  69. }
  70. void find_scc()
  71. {
  72. for (int i = ; i <= n; i++)
  73. {
  74. if (!pre[i])
  75. dfs(i);
  76. }
  77. }
  78. void build_new_graphic()
  79. {
  80. for (int i = ; i <= n; i++)
  81. {
  82. for (int j = ; j <= n; j++)
  83. {
  84. if (i != j && sccno[i] != sccno[j] && g[i][j] != INF) // 不同的连通分量号建立一条有向边。
  85. {
  86. G[ sccno[i] ][ sccno[j] ] = min(g[i][j], G[ sccno[i] ][ sccno[j] ]);
  87. }
  88. }
  89. }
  90. }
  91. int dist[Max], vis[Max];
  92. void dijkstra(int start, int goal)
  93. {
  94. //利用起点start,终点goal来搞,以前做惯了,直接用起点是1来做了
  95. for (int i = ; i <= scc_cnt; i++)
  96. dist[i] = G[start][i];
  97. memset(vis, , sizeof(vis));
  98. dist[start] = ;
  99. vis[start] = ;
  100. for (int i = ; i <= scc_cnt; i++)
  101. {
  102. int minn = INF, pos = ; // 这里初始化pos为1,否则当下面的循环不满足条件是,执行vis[pos]会出错
  103. for (int j = ; j <= scc_cnt; j++)
  104. {
  105. if (!vis[j] && minn > dist[j])
  106. {
  107. minn = dist[j];
  108. pos = j;
  109. }
  110. }
  111. vis[pos] = ;
  112. for (int j = ; j <= scc_cnt; j++)
  113. {
  114. if (!vis[j] && dist[j] > dist[pos] + G[pos][j])
  115. dist[j] = dist[pos] + G[pos][j];
  116. }
  117. }
  118. if (dist[goal] != INF)
  119. printf("%d\n", dist[goal]);
  120. else
  121. printf("Nao e possivel entregar a carta\n");
  122. }
  123. int main()
  124. {
  125. while (scanf("%d%d", &n, &m) != EOF)
  126. {
  127. if (n == && m == )
  128. break;
  129. init();
  130. int u, v, c;
  131. for (int i = ; i <= m; i++)
  132. {
  133. scanf("%d%d%d", &u, &v, &c);
  134. if (g[u][v] > c)
  135. {
  136. g[u][v] = c; // 判断重边
  137. }
  138. addEdge(u, v);
  139. }
  140. find_scc(); // 找强连通分量
  141. //cout << scc_cnt << endl;
  142. build_new_graphic(); // 重新构图
  143.  
  144. int k;
  145. scanf("%d", &k);
  146. while (k--)
  147. {
  148. scanf("%d%d", &u, &v);
  149. if (sccno[u] == sccno[v]) // 同一连通分量直接输出
  150. printf("0\n");
  151. else
  152. {
  153. dijkstra(sccno[u], sccno[v]);
  154. }
  155. }
  156. printf("\n");
  157. }
  158.  
  159. return ;
  160. }

POJ3114 Countries in War (强连通分量 + 缩点 + 最短路径 + 好题)的更多相关文章

  1. Countries in War(强连通分量及其缩点)

    http://poj.org/problem?id=3114 题意:有n个城市,m条边,由a城市到b城市的通信时间为w,若a城市与b城市连通,b城市与a城市也连通,则a,b城市之间的通信时间为0,求出 ...

  2. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  3. POJ1236Network of Schools(强连通分量 + 缩点)

    题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...

  4. HD2767Proving Equivalences(有向图强连通分量+缩点)

    题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...

  5. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...

  6. ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)

    题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...

  7. POJ2553 The Bottom of a Graph(强连通分量+缩点)

    题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: #include<cstdio&g ...

  8. uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...

  9. poj 2762 Going from u to v or from v to u?(强连通分量+缩点重构图+拓扑排序)

    http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit:  ...

随机推荐

  1. 子Div使用Float后如何撑开父Div

    如果想要撑开父元素可以采用以下方法: 方法一: 父元素设置overflow以及zoom,样式如下: 1 <style> 2   #div1{border:1px solid red;ove ...

  2. 新时代的coder如何成为专业程序员

    在移动互联网"泛滥"的今天,越来越多非专业(这里的非专业指的是非计算机专业毕业的程序员)程序员加入到了IT行业中来了,可能是因为移动互联网的火爆导致程序员容易就业而且工资很高,可能 ...

  3. 用canvas 实现个图片三角化(LOW POLY)效果

    之前无意中看到Ovilia 用threejs做了个LOW POLY,也就是图片平面三角化的效果,觉得很惊艳,然后就自己花了点时间尝试了一下. 我是没怎么用过threejs,所以就直接用canvas的2 ...

  4. KM模板

    var n,m,i,j:longint; ans:int64; sel,lx,ly,slack:..] of int64; a:..,..] of int64; visx,visy:..] of bo ...

  5. Ryu

    What's Ryu? Ryu is a component-based software defined networking framework. Ryu provides software co ...

  6. C语言printf()函数:格式化输出函数

    C语言printf()函数:格式化输出函数 头文件:#include <stdio.h> printf()函数是最常用的格式化输出函数,其原型为:     int printf( char ...

  7. 第八章:Java集合

    1.Java集合 A:对象的容器. B:实现数据结构(栈.队列) 2.  Set:无序不重复 List: 有序可重复,长度可变. Map: 存放键值对. 3.  Iterator foreach

  8. sublime package control 被墙的解决方法

    在host里面配置 50.116.34.243 sublime.wbond.net 好用的插件地址 http://www.thinkphp.cn/topic/37057.html

  9. iOS开发小技巧--实现将图片保存到本地相册

    一.报错的代码 错误 -- out of bounds 超出界限的意思 *** Terminating app due to uncaught exception 'NSInvalidArgument ...

  10. 【BZOJ 3529】【SDOI 2014】数表

    看Yveh的题解,这道题卡了好长时间,一直不明白为什么要······算了当时太naive我现在都不好意思说了 #include<cstdio> #include<cstring> ...