【agc004f】Namori Grundy

那个问一下有人可以解释以下这个做法嘛,看不太懂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[200010],g[200010];
 11 int n,ehead[200010],ghead[200010];
 12 int m=0,a[200010]={0},out[200010]={0};
 13 int val[200010];
 14 bool vis[200010]={false};
 15 queue<int>q;
 16 stack<int>s[200010];
 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=-1;
 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==-1){
 28         if(w==-1){
 29             for(int i=0;;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=0;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==-1){
 52         int flag=-1;
 53         bool ret=false;
 54         for(int i=0;;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>-1)
 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=-1;
 70     for(int i=0;i<w;i++)
 71         if(s[i].top()!=u){
 72             if(flag>-1){
 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,-1,sizeof(ehead));
 88     memset(ghead,-1,sizeof(ghead));
 89     memset(val,-1,sizeof(val));
 90     while(!q.empty())q.pop();
 91     scanf("%d",&n);
 92     for(int i=0;i<=n;i++){
 93         while(!s[i].empty())
 94             s[i].pop();
 95         s[i].push(0x3f3f3f3f);
 96     }
 97     for(int i=1,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=1;i<=n;i++)
105         if(out[i]==0){
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=0;;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]==0){
125                 vis[g[i].to]=true;
126                 q.push(g[i].to);
127             }
128     }
129     if(m==n){
130         puts("POSSIBLE");
131         return 0;
132     }
133     if(m==0){
134         puts(n&1?"IMPOSSIBLE":"POSSIBLE");
135         return 0;
136     }
137     for(int i=1;i<=n;i++)
138         if(!vis[i]){
139             puts(dfs(i,-1,-1)?"POSSIBLE":"IMPOSSIBLE");
140             return 0;
141         }
142     return 0;
143 }

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

转载于:https://www.cnblogs.com/gzez181027/p/agc004f.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279531.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

找到特定ip地址 修改ip_您如何找到网站的IP地址?

找到特定ip地址 修改ipWhether you are in it just for a bit of geeky fun, or are seriously wanting to know the answer, how do you find out the IP address for a website? Today’s SuperUser Q&A post looks at the answer, and how to know if more than one we…

Rational Rose 2003 下载、破解及安装方法(图文)

方法一&#xff1a; 1、安装Rational Rose2003时&#xff0c;在需选择安装项的时候&#xff0c;只选择Rational Rose EnterPrise Edition即可&#xff0c;不需选择其他项&#xff0c;之后选择“DeskTop Installation from CD Image“&#xff0c;一路下一步。出现Mem_pointer_B…

数据结构:莫队

莫队算法是用来处理一类无修改的离线区间询问问题 莫队的精髓就在于&#xff0c;离线得到了一堆需要处理的区间后&#xff0c;合理的安排这些区间计算的次序以得到一个较优的复杂度 代表题目是BZOJ2038这道题 进行区间询问[l,r]&#xff0c;输出该区间内随机抽两次抽到相同颜色…

【学习笔记】第三章 python3核心技术与实践--Jupyter Notebook

可能你已经知道&#xff0c;Python 在 14 年后的“崛起”&#xff0c;得益于机器学习和数学统计应用的兴起。那为什么 Python 如此适合数学统计和机器学习呢&#xff1f;作为“老司机”的我可以肯定地告诉你&#xff0c;Jupyter Notebook &#xff08;https://jupyter.org/&…

二进制安位处理_处理器与安​​全性之间的联系是什么?

二进制安位处理Newer processors are able to contribute to the security of your system, but what exactly do they do to help? Today’s Super User Q&A post looks at the link between processors and system security. 较新的处理器能够为您的系统安全做出贡献&am…

李开复现身说法成功的十个启发

http://blog.sina.com.cn/kaifulee自信不失谦虚&#xff0c;谦虚不失自信天赋就是兴趣 兴趣就是天赋思考比传道重要 观点比解惑重要我不同意你 但我支持你挫折不是惩罚 而是学习的机会创新不重要 有用的创新才重要完美的工作 成长兴趣 影响力用勇气改变可以改变的事情做最好的领…

关于width: 100%的一些看法

一.position对width 设置为百分比的影响<html><head><style type"text/css">img {width: 50%}body {margin: 8px;}</style> </head><body><div style" min-height: 10px; background: red; "><div><im…

Haproxy+多台MySQL从服务器(Slave) 实现负载均衡

本系统采用MySQL一主多从模式设计&#xff0c;即1台 MySQL“主”服务器(Master)多台“从”服务器(Slave)&#xff0c;“从”服务器之间通过Haproxy进行负载均衡&#xff0c;对外只提供一个访问IP&#xff0c;当程序需要访问多台"从"服务器时&#xff0c;只需要访问Ha…

爱普生第三方相机_值得购买第三方相机镜头吗?

爱普生第三方相机When people buy a Canon or Nikon camera, they often assume that they can only buy Canon or Nikon lenses. But that isn’t true. While Nikon lenses won’t work on your Canon camera, there are third-party lens manufacturers—such as Sigma, Tam…

[BZOJ4182]Shopping

description 权限题。 树上\(n\)个节点每个节点都有一种物品&#xff0c;每种物品有其价值&#xff0c;价格&#xff0c;数量&#xff0c;只能买一个连通块中的物品&#xff0c;求\(m\)元能买到物品价值的最大值。 data range \[ n\le 500,m\le 4000,T\le 5,c_i\le m\] solutio…

如何用 Flutter 实现混合开发?闲鱼公开源代码实例

2019独角兽企业重金招聘Python工程师标准>>> 具有一定规模的 App 通常有一套成熟通用的基础库&#xff0c;尤其是阿里系 App&#xff0c;一般需要依赖很多体系内的基础库。那么使用 Flutter 重新从头开发 App 的成本和风险都较高。所以在 Native App 进行渐进式迁移…

Silverlight之工具箱使用1

我们在开发Silverlight项目时必定需要使用VS自带的一些控件&#xff0c;但是这些有限的控件有时候难以满足开发时的需求&#xff0c;因此MS给我们大家提供另外一套工具&#xff0c;来缓解Silverlight开发包的不足。此工具箱免费下载地址是&#xff1a;http://silverlight.codep…

apple tv设置_如何设置Apple HomePod

apple tv设置Apple’s HomePod smart speaker is finally here. If you bought one and are eager to get going, here’s how to set it up. 苹果的HomePod智能扬声器终于来了。 如果您购买了一个并且渴望上手&#xff0c;请按照以下步骤进行设置。 First off, before you eve…

leetcode 128最长连续序列

方法一&#xff1a;使用快排&#xff1a; //排序法&#xff0c;时间O(nlogn)&#xff0c;使用STL&#xff0c;只是验证一下思想&#xff0c;非正解&#xff1b; class Solution { public:int longestConsecutive(vector<int>& nums) {sort(nums.begin(),nums.end());…

8月19学习练习[两三个TableView并排显示]

要求&#xff1a;在一个view中显示两个tableView&#xff0c;要求左右显示的内容以及行数不一样&#xff0c;且左边每行显示两张图片&#xff08;分别3个一轮回&#xff0c;2个一轮回&#xff09;并且显示中国的城市名&#xff0c;右边显示水果名。点击时分别显示城市名或水果名…

word多级列表创建目录_如何在Microsoft Word中创建和使用多级列表

word多级列表创建目录Microsoft Word lets you easily create and format multilevel lists in your documents. You can choose from a variety of formatting options, including bulleted, numbered, or alphabetized lists. Let’s take a look. Microsoft Word使您可以轻松…

如何将多个Android Wear手表与单个手机配对

When it comes to “regular” wristwatches, a lot of people have different watches for different activities. It makes sense—a sporty watch for the gym, a nicer watch for the office, and a casual watch for everything else. If you want to live this life with…

Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(3)...

提供引用计数器的类RefBase我们就暂时介绍到这里&#xff0c;后面我们再结合智能指针类一起分析&#xff0c;现在先来看看强指针类和弱指针类的定义。强指针类的定义我们在前面介绍轻量级指针的时候已经见到了&#xff0c;就是sp类了&#xff0c;这里就不再把它的代码列出来了。…

ref:下一个项目为什么要用 SLF4J

ref:http://blog.mayongfa.cn/267.html 阿里巴巴 Java 开发手册 前几天阿里巴巴在云栖社区首次公开阿里官方Java代码规范标准&#xff0c;就是一个PDF手册&#xff0c;有命名规范&#xff0c;让你知道自己原来取的每一个类名、变量名都是烂名字&#xff0c;真替你家未来孩子担心…

洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)

题面 传送门 题解 日常敲板子.jpg //minamoto #include<bits/stdc.h> #define R register #define inline __inline__ __attribute__((always_inline)) #define fp(i,a,b) for(R int i(a),I(b)1;i<I;i) #define fd(i,a,b) for(R int i(a),I(b)-1;i>I;--i) #define …