【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.pswp.cn/news/279531.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279531.shtml
英文地址,請注明出處:http://en.pswp.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 …