ABC216 D - Pair of Balls(拓撲排序)
阿新 • • 發佈:2021-08-30
D - Pair of Balls
題意
有\(N\)種顏色的球,每種顏色有\(2\)個,共\(2N\)個球,現將它們放置在\(M\)個棧中,每個棧有\(k_i\)個球,每次從兩個不同的棧頂取出相同顏色的球,問是否能夠取完,可以則輸出\(Yes\),否則輸出\(No\)。
思路
我們可以將每個棧看成一個單鏈表,從棧頂連向棧底,因此當我們可以選擇某種顏色出棧的時候,說明此時沒有邊連向該種顏色,也就可以認為是入度為\(0\)的時候可以出棧,那麼問題就可以轉化成為拓撲排序能否執行\(n\)次。因此我們只需要建圖再跑一遍拓撲排序即可。
參考程式碼
點此展開
//Author:Daneii #include <bits/stdc++.h> using namespace std; //快讀 template <typename T>inline void read(T& t) { int f=0; t=0; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=1; ch=getchar(); } while(isdigit(ch)) { t=t*10+ch-48; ch=getchar(); } t=f?-t:t; } template <typename T,typename... Args> inline void read(T& t, Args&... args){read(t);read(args...);} const int N=2e5+10; int n,m; vector<int> g[N]; int deg[N]; bool topsort() { queue<int> q; for(int i=1;i<=n;i++) if(!deg[i]) q.push(i); int cnt=0; while(q.size()) { auto tmp=q.front(); q.pop(); cnt++; for(auto x:g[tmp]) { if(--deg[x]==0) { q.push(x); } } } return cnt==n; } int main() { read(n,m); for(int i=1;i<=m;i++) { int k; read(k); int u=0,v; for(int j=1;j<=k;j++) { if(j==1) read(u); else { read(v); g[v].push_back(u); deg[u]++; u=v; } } } if(topsort()) puts("Yes"); else puts("No"); return 0; }