【题意】

见:http://blog.csdn.net/ascii991/article/details/7466278

【思路】

缩点+tarjan,思路也可以到上面的博客去看。(吐槽:这道题其实我没有AC。我过了当年IOI的数据,而把别人AC掉的程序带进去,明显过不了IOI的数据!求POJ修正一下!)我在这里引用一下:

找强连通分量,缩点。记f[i]为缩完点后的新图中各点入度,g[i]为出度,ans1为f[i]==0的点的数目,ans2为g[i]==0的点的数目则第一问为ans1,第二问则为max{ans1,ans2}。

至于第二问的解释,我的想法是对于得到的DAG图,考虑其中的出度为0的点和入度为0的点组成的点集V,将这些点相连,最多这需要max{ans1,ans2}条边,就能使整个图成为强连通分量。

但是请注意,大家可能都没发现,这个结论的前提是DAG图是连通的情况下才成立。如果DAG图有多个连通分量,则还要考虑将多个连通分量合并的所需代价。幸运的是,这道题保证了只有一个连通分量。(题目第一句话所说)

【错误点】

1.tarjan要进行多次,详见程序注释

2.循环从0开始还是从1开始要看清楚!

3.但只有一个连通分量的时候,不需要再增加边!

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<vector>
  6. #include<stack>
  7. using namespace std;
  8. const int MAXN=+;
  9. int n;//学校的总数
  10. int u[MAXN],v[MAXN];//记录每一条边的起始点和终点
  11. int sp[MAXN];//记录缩点之后每个点对应的编号
  12. int tot=;//有向图中边的总数
  13. int vis[MAXN];
  14. int instack[MAXN];
  15. int dfn[MAXN],low[MAXN];
  16. int indegree[MAXN],outdegree[MAXN];//记录缩点后的每一个点的入度与出度
  17. vector<int> E[MAXN];
  18. stack<int> S;
  19. int T=;
  20. int cnt=;//为缩点后的每一个点编号
  21.  
  22. void tarjan(int u)
  23. {
  24. dfn[u]=low[u]=++T;
  25. vis[u]=;
  26. S.push(u);
  27. instack[u]=;
  28.  
  29. for (int i=;i<E[u].size();i++)
  30. {
  31. int son=E[u][i];
  32. if (!vis[son])
  33. {
  34. tarjan(son);
  35. low[u]=min(low[son],low[u]);
  36. }
  37. else
  38. if (vis[son] && instack[son])
  39. low[u]=min(dfn[son],low[u]);
  40. }
  41.  
  42. if (dfn[u]==low[u])
  43. {
  44. cnt++;
  45. int x;
  46. do
  47. {
  48. x=S.top();
  49. S.pop();
  50. sp[x]=cnt;
  51. instack[x]=;
  52. }while (x!=u);
  53. }
  54. }
  55.  
  56. void init()
  57. {
  58. memset(vis,,sizeof(vis));
  59. memset(instack,,sizeof(instack));
  60. scanf("%d",&n);
  61. for (int i=;i<=n;i++)
  62. {
  63. int to;
  64. while (scanf("%d",&to) && to)
  65. {
  66. tot++;
  67. u[tot]=i;v[tot]=to;
  68. E[i].push_back(to);
  69. }
  70. }
  71. }
  72.  
  73. void find()
  74. {
  75. memset(indegree,,sizeof(indegree));
  76. memset(outdegree,,sizeof(outdegree));
  77. if (cnt>)
  78. {
  79. for (int i=;i<=tot;i++)
  80. /*错误点:写成了i=0;i<tot,导致有时候没有进入循环!*/
  81. {
  82. if (sp[u[i]]!=sp[v[i]])
  83. {
  84. outdegree[sp[u[i]]]++;
  85. indegree[sp[v[i]]]++;
  86. }//找出缩点后各点的出度和入度
  87. }
  88.  
  89. int noin=,noout=;
  90. for (int i=;i<=cnt;i++)
  91. {
  92. if (indegree[i]==) noin++;
  93. if (outdegree[i]==) noout++;
  94. }
  95. cout<<noin<<endl;
  96. cout<<max(noin,noout)<<endl;
  97. }
  98. else if (cnt==) printf("1\n\0\n");
  99. }
  100.  
  101. int main()
  102. {
  103. init();
  104. for (int i=;i<=n;i++) if (vis[i]==) tarjan(i);
  105. /*错误点:一开始直接tarjan(1)了,导致有一些学校没有被访问到!每次随机从没有访问的某个结点开始!*/
  106. find();
  107. return ;
  108. }

【tarjan+缩点】POJ1236[IOI1996]-Network of Schools的更多相关文章

  1. POJ1236:Network of Schools (思维+Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24880   Accepted: 99 ...

  2. poj1236/luogu2746 Network of Schools (tarjan)

    tarjan缩点后,第一问答案显然是入度为零的点得个数第二问:考虑到 没有入度或出度为0的点 的图强连通, 所以答案就是max{入度为零的个数,出度为零的个数} (把出度为零的连到入度为零的点,然后剩 ...

  3. 【poj1236】 Network of Schools

    http://poj.org/problem?id=1236 (题目链接) 题意 给定一个有向图,求:1.至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点:2.至少要加多少条边,才能使得从任 ...

  4. POJ1236:Network of Schools——题解

    http://poj.org/problem?id=1236 首先还是缩点,然后入度为0的点的个数就是你要投文件个数. 然后我们对于入度和出度为0的点的个数取最大值即为答案. (简单证明:入度和出度为 ...

  5. poj1236 Network of Schools【强连通分量(tarjan)缩点】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html  ---by 墨染之樱花 [题目链接]http://poj.org/pr ...

  6. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

  7. Network of Schools --POJ1236 Tarjan

    Network of Schools Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are conne ...

  8. POJ1236 - Network of Schools tarjan

                                                     Network of Schools Time Limit: 1000MS   Memory Limi ...

  9. POJ1236 Network of Schools (强连通)(缩点)

                                                                Network of Schools Time Limit: 1000MS   ...

随机推荐

  1. web_一些常用的线上脚本地址记录(个人使用)

    1.jquery <script src="http://code.jquery.com/jquery-1.4.1.min.js"></script> 2. ...

  2. 编译zpool命令

    环境:192.168.50.239(在 illumos源码中编译zpool命令) PS:由于对zpool命令的工作原理不熟悉,所以编译,可在其中加入调试语句来明白其原理 首先介绍 illumos-so ...

  3. Java多线程学习(四)等待/通知(wait/notify)机制

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  4. webpack版本1与版本2的若干写法区别

    2.x的环境遇到类似this._init is not a function的报错. 版本1.x的写法: resolve: { extensions: ['', '.js', '.vue'] }, m ...

  5. sicily 1009. Mersenne Composite N

    Description One of the world-wide cooperative computing tasks is the "Grand Internet Mersenne P ...

  6. dos命令连接mysql并且查看编码方式

    打开cmd: 输入:mysql -hlocalhost -uroot -p 然后: show variables like 'char%';

  7. python初学-元组、集合

    元组: 元组基本和列表一样,区别是 元组的值一旦创建 就不能改变了 tup1=(1,2,3,4,5) print(tup1[2]) ---------------------------------- ...

  8. linux命令(45):diff命令

    1.命令格式: diff[参数][文件1或目录1][文件2或目录2] 2.命令功能: diff命令能比较单个文件或者目录内容.如果指定比较的是文件,则只有当输入为文本文件时才有效.以逐行的方式,比较文 ...

  9. Codeforces 873B - Balanced Substring(思维)

    题目链接:http://codeforces.com/problemset/problem/873/B 题目大意:一个字符串全部由‘0’和‘1’组成,当一段区间[l,r]内的‘0’和‘1’个数相等,则 ...

  10. jquery中的done和always解决ajax问题

    昨天写一个跨域请求json数据的实例.遇到传值问题,尝试了各种方式都不行,后来发现,同一个地址,同一个ip请求次数频繁传值相同的话,ajax会默认跟一个&?时间戳,这就导致我传过去的值是错误的 ...