CF915D Almost Acyclic Graph
阿新 • • 發佈:2020-08-23
前言
重新認識拓撲排序
題目
講解
首先我們考慮暴力列舉刪的邊,然後跑topu判環
時間複雜度\(O(m^2)=O(TLE)\)
但是列舉每一條邊真的有必要嗎?
我們想到列舉一條邊後無非就是讓一個點的入度減一罷了
為什麼不直接列舉讓哪個點入度減一呢?
時間複雜度\(O(nm)=O(AC)\)
程式碼
int head[MAXN],tot; struct edge { int v,nxt; }e[MAXM]; void Add_Edge(int x,int y) { e[++tot].v = y; e[tot].nxt = head[x]; head[x] = tot; } int ru[MAXN],ru1[MAXN]; queue<int> q; bool topu() { for(int i = 1;i <= n;++ i) ru[i] = ru1[i]; for(int i = 1;i <= n;++ i) if(!ru[i]) q.push(i); int cnt = 0; while(!q.empty()) { int t = q.front();q.pop(); cnt++; for(int i = head[t]; i ;i = e[i].nxt) { ru[e[i].v]--; if(!ru[e[i].v]) q.push(e[i].v); } } return cnt == n; } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); n = Read(); m = Read(); for(int i = 1;i <= m;++ i) { int u = Read(),v = Read(); Add_Edge(u,v);ru1[v]++; } for(int i = 1;i <= n;++ i) { if(ru1[i]) { ru1[i]--; if(topu()) {printf("YES");return 0;} ru1[i]++; } } printf("NO"); return 0; }