题解 CF915D 【Almost Acyclic Graph】

这道题我第一次的想法是直接判环的数量,然而事实证明实在是太naive了。

随便画个图都可以卡掉我的解法。(不知道在想什么)


这道题的正解是拓扑排序。

朴素的想法是对所有边都跑一次拓扑,但这样O(m(n+m))会炸,于是可以有下面的优化。

我们找到所有入度不为零的点,然后把他们每一个都删掉一条边跑一遍拓扑排序。

那么这样就可以优化到O(n(n+m))了,稳得一批。


AC代码如下:

1935ms 1356kb

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 namespace StandardIO {
 6 
 7     template<typename T>inline void read (T &x) {
 8         x=0;T f=1;char c=getchar();
 9         for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
10         for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
11         x*=f;
12     }
13 
14     template<typename T>inline void write (T x) {
15         if (x<0) putchar('-'),x*=-1;
16         if (x>=10) write(x/10);
17         putchar(x%10+'0');
18     }
19 
20 }
21 
22 using namespace StandardIO;
23 
24 namespace Solve {
25     
26     const int N=505;
27     
28     int n,m;
29     vector<int>graph[N];
30     int indeg[N];
31     queue<int>q;
32     
33     inline bool toposort (int n) {
34         int temp[N],size=0;
35         memcpy(temp,indeg,sizeof(indeg));
36         while (!q.empty()) q.pop();
37         for (register int i=1; i<=n; ++i) {
38             if (temp[i]==0) q.push(i),size++;
39         }
40         while (!q.empty()) {
41             int v=q.front();q.pop();
42             for (register int i=0; i<graph[v].size(); ++i) {
43                 int to=graph[v][i];
44                 temp[to]--;
45                 if (temp[to]==0) q.push(to),size++;
46             }
47         }
48         return size>=n;
49     }
50     
51     inline void solve () {
52         read(n),read(m);
53         for (register int i=1; i<=m; ++i) {
54             int x,y;
55             read(x),read(y);
56             indeg[y]++;
57             graph[x].push_back(y);
58         }
59         for (register int i=1; i<=n; ++i) {
60             if (indeg[i]!=0) {
61                 indeg[i]--;
62                 if (toposort(n)) {
63                     puts("YES");
64                     return;
65                 }
66                 indeg[i]++;
67             }
68         }
69         puts("NO");
70     }
71 }
72 
73 using namespace Solve;
74 
75 int main () {
76 //    freopen(".in","r",stdin);
77 //    freopen(".out","w",stdout);
78     solve();
79 }

猜你喜欢

转载自www.cnblogs.com/ilverene/p/9841097.html