那个问一下有人可以解释以下这个做法嘛,看不太懂QwQ~


Description

有一个n个点n条边的有向图,点的编号为从1到n。

给出一个数组p,表明有(p1,1),(p2,2),…,(pn,n)这n条单向边,这n条边必定构成弱连通图。

每个点均有一个权值ai,满足以下性质:

(1)所有ai均为非负整数;

(2)对于任意边(i,j),有ai≠aj

(3)对于任意i,x(0≤x<ai),均有(i,j)满足aj=ai

判断这样的图是否存在。(“POSSIBLE”/“IMPOSSIBLE”)


Solution

(早上花了三个小时还打挫了,心态爆炸)

弱连通图:若该有向图所有边为双向边时,满足该图为连通图,则该有向图为弱连通图。

我们容易发现,当一个点的出度为0时,它的权值也为0。我们可以对每一条边建反向边,然后进行拓扑排序,每次对新图中入度为0的点求出权值,然后删去。

若最后有剩余的点,由于原图中每个点的入度均为1,则这些点形成一个环,取其中任意一个点开始遍历即可。特别地,若原图n个点构成环,则偶环存在而奇环不存在。

下面讲一下如何求出每个点的权值:

拓扑排序:

若该点在原图中为叶子节点,则权值为0;

若不为叶子节点,则权值为原图子节点权值中未出现的数的最小值。

环:

记录原图中该点不在环上的子节点权值中未出现的数的最小值a与次小值b。若该点权值为a,则下一点无限制;若该点权值为b,则下一点权值必为a。在跑环的时候,注意判断相邻两点权值不相等以及子节点权值满足条件(2)(3)即可。

Code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<queue>
  5. #include<stack>
  6. using namespace std;
  7. #define next _next
  8. struct edge{
  9. int to,next;
  10. }e[],g[];
  11. int n,ehead[],ghead[];
  12. int m=,a[]={},out[]={};
  13. int val[];
  14. bool vis[]={false};
  15. queue<int>q;
  16. stack<int>s[];
  17. bool dfs(int u,int w,int cannot){
  18. for(int i=ehead[u];~i;i=e[i].next)
  19. if(vis[e[i].to])
  20. s[val[e[i].to]].push(u);
  21. int v=-;
  22. for(int i=ehead[u];~i;i=e[i].next)
  23. if(!vis[e[i].to]){
  24. v=e[i].to;
  25. break;
  26. }
  27. if(v==-){
  28. if(w==-){
  29. for(int i=;;i++)
  30. if(s[i].top()!=u){
  31. val[u]=i;
  32. break;
  33. }
  34. }
  35. else{
  36. val[u]=w;
  37. for(int i=;i<w;i++)
  38. if(s[i].top()!=u){
  39. for(int i=ehead[u];~i;i=e[i].next)
  40. if(vis[e[i].to])
  41. s[val[e[i].to]].pop();
  42. return false;
  43. }
  44. }
  45. bool ret=(val[u]!=cannot&&s[val[u]].top()!=u);
  46. for(int i=ehead[u];~i;i=e[i].next)
  47. if(vis[e[i].to])
  48. s[val[e[i].to]].pop();
  49. return ret;
  50. }
  51. if(w==-){
  52. int flag=-;
  53. bool ret=false;
  54. for(int i=;;i++)
  55. if(s[i].top()!=u){
  56. vis[u]=true;
  57. if(i!=cannot)
  58. ret|=dfs(v,flag,val[u]=i);
  59. vis[u]=false;
  60. if(flag>-)
  61. break;
  62. flag=i;
  63. }
  64. for(int i=ehead[u];~i;i=e[i].next)
  65. if(vis[e[i].to])
  66. s[val[e[i].to]].pop();
  67. return ret;
  68. }
  69. int flag=-;
  70. for(int i=;i<w;i++)
  71. if(s[i].top()!=u){
  72. if(flag>-){
  73. for(int i=ehead[u];~i;i=e[i].next)
  74. if(vis[e[i].to])
  75. s[val[e[i].to]].pop();
  76. return false;
  77. }
  78. flag=i;
  79. }
  80. bool ret=(w!=cannot&&s[w].top()!=u&&dfs(v,flag,val[u]=w));
  81. for(int i=ehead[u];~i;i=e[i].next)
  82. if(vis[e[i].to])
  83. s[val[e[i].to]].pop();
  84. return ret;
  85. }
  86. int main(){
  87. memset(ehead,-,sizeof(ehead));
  88. memset(ghead,-,sizeof(ghead));
  89. memset(val,-,sizeof(val));
  90. while(!q.empty())q.pop();
  91. scanf("%d",&n);
  92. for(int i=;i<=n;i++){
  93. while(!s[i].empty())
  94. s[i].pop();
  95. s[i].push(0x3f3f3f3f);
  96. }
  97. for(int i=,x;i<=n;i++){
  98. scanf("%d",&x);
  99. e[i]=(edge){i,ehead[x]};
  100. g[i]=(edge){x,ghead[i]};
  101. ehead[x]=ghead[i]=i;
  102. a[x]++;out[x]++;
  103. }
  104. for(int i=;i<=n;i++)
  105. if(out[i]==){
  106. vis[i]=true;
  107. q.push(i);
  108. }
  109. while(!q.empty()){
  110. int u=q.front();
  111. q.pop();m++;
  112. for(int i=ehead[u];~i;i=e[i].next)
  113. s[val[e[i].to]].push(u);
  114. for(int i=;;i++)
  115. if(s[i].top()!=u){
  116. val[u]=i;
  117. break;
  118. }
  119. for(int i=ehead[u];~i;i=e[i].next)
  120. s[val[e[i].to]].pop();
  121. for(int i=ghead[u];~i;i=g[i].next)
  122. out[g[i].to]--;
  123. for(int i=ghead[u];~i;i=g[i].next)
  124. if(out[g[i].to]==){
  125. vis[g[i].to]=true;
  126. q.push(g[i].to);
  127. }
  128. }
  129. if(m==n){
  130. puts("POSSIBLE");
  131. return ;
  132. }
  133. if(m==){
  134. puts(n&?"IMPOSSIBLE":"POSSIBLE");
  135. return ;
  136. }
  137. for(int i=;i<=n;i++)
  138. if(!vis[i]){
  139. puts(dfs(i,-,-)?"POSSIBLE":"IMPOSSIBLE");
  140. return ;
  141. }
  142. return ;
  143. }

(话说环套树的题是真的烦[○・`Д´・ ○])

【agc004f】Namori Grundy的更多相关文章

  1. 【agc004F】Namori

    Portal -->agc004F Solution  好神仙的转化qwq ​  首先我们可以先考虑\(m=n-1\)的情况下,也就是树的情况下要怎么做  我们可以将这个问题转化一下:我们对这颗 ...

  2. 【ARC079F】Namori Grundy

    Description 题目链接 大意:给一张基环外向树.要求给每一个点确定一个值,其值为所有后继点的\(\text{mex}\).求是否存在确定权值方案. Solution 首先,对于叶子节点,其权 ...

  3. 【atcoder F - Namori】**

    F- Namori http://agc004.contest.atcoder.jp/tasks/agc004_f Time limit : 2sec / Memory limit : 256MB S ...

  4. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  5. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  6. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  8. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  9. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

随机推荐

  1. MYSQL binlog 日志内容查看

    记录mysql数据库真正执行更改的所有操作(DML语句),不包含那些没有修改任何数据的语句,不会记录select和show这样的语句. 二进制日志的作用: 1. 可以完成主从复制的功能 2. 进行恢复 ...

  2. SSIS故障排除

    1.2015.09.10 SSIS部署到SQL Server上 JOB任务无法执行 说是sa账户没有执行权限 解决办法:1)SQL Server 启动时使用windows管理员账户登录.2)部署的数据 ...

  3. 我网站用session做的登录,为什么清除浏览器数据后还是得重新登录?session是存在服务器上的。

    答案一: 你清除了浏览器数据,相当于把cookie也清了,那么你的sessionId也就没有了,所以你再次请求的时候服务器无法根据你携带的sessionid来获取对应的session,所以说需要重新登 ...

  4. 51nod 1402 最大值 3级算法题 排序后修改限制点 时间复杂度O(m^2)

    代码: 题意,第一个数为0,相邻的数相差0或者1,有一些点有限制,不大于给定值,求这组数中可能的最大的那个数. 这题我们看一个例子:第5个数的限制为2 1 2 3 4 5 6 7 8 9 0 1 2 ...

  5. ASP.NET 让ajax请求webform后台方法

    $.ajax({ type: "POST", url: ".aspx/getSubjectDirection", data: JSON.stringify({ ...

  6. Good Bye 2014 B. New Year Permutation 【传递闭包 贪心】

    解题思路:给出一列数an,再给出一个矩阵d[i][j],在满足d[i][j]=1的情况下,称a[i]和a[j]可以交换,问经过交换最后得到字典序最小的数列a[n] 首先是贪心的思想,大的能换就换到后面 ...

  7. QT+OpenCV进行图像采集最小时延能够达到20ms

    得到“算法高性能”项目的支持,目前成功地在Win10上运行WB2,感觉目前的代码速度慢.响应慢.CPU占用比例高.这种情况下3399上能够运行,说明这个平台已经是很强的了.下一步,首先在Windows ...

  8. 带参数,头信息,代理,cookie爬取

    1.get传参 (1)汉字报错 :解释器器ascii没有汉字 url汉字转码 urllib.parse.quote safe="string.printtable" (2)字典传参 ...

  9. jQuery第一课 加载页面弹出一个对话框

    <script type="text/javascript"> $(document).ready(function(){ alert("欢迎收看:" ...

  10. java几种远程服务调用协议的比较

    原文地址:http://www.cnblogs.com/jifeng/archive/2011/07/20/2111183.html 一.综述 本文比较了RMI,Hessian,Burlap,Http ...