Almost Acyclic Graph Codeforces - 915D

以前做过的题都不会了。。。。

此题做法:优化的暴力

有一个显然的暴力:枚举每一条边试着删掉

注意到题目要求使得图无环,那么找出图上任意一个环,都应当要在其某一处断开(当然没有环是YES)

因此找出图中任意一个简单环(点不重复),枚举断开其上每一条边即可(共最多n条边)

复杂度O(n*(n+m))

注意:不能用拓扑排序找出不能被排序的点来找环,因为拓扑排序后入度不为0的不一定是环上的点(比如可能是某个点,没有出边,仅有一条入边,是某个环上的点引出的)(曾经错了)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<vector>
  4 #include<queue>
  5 #define pb push_back
  6 using namespace std;
  7 int n,m,aa,bb;
  8 vector<int> e[510],ann;
  9 queue<int> q;
 10 int ma[510],in[510],st;
 11 bool fl,ok[510];
 12 namespace Tarjan
 13 {
 14 int s[510],dfn[510],low[510],dfc,top,sccnum[510],sccc,sz[510];
 15 void dfs(int u)
 16 {
 17     dfn[u]=low[u]=++dfc;
 18     s[++top]=u;
 19     for(auto v:e[u])
 20     {
 21         if(!dfn[v])
 22         {
 23             dfs(v);
 24             low[u]=min(low[u],low[v]);
 25         }
 26         else if(!sccnum[v])
 27             low[u]=min(low[u],dfn[v]);
 28     }
 29     if(low[u]==dfn[u])
 30     {
 31         sccc++;
 32         while(top&&s[top]!=u)    sccnum[s[top--]]=sccc;
 33         sccnum[s[top--]]=sccc;
 34     }
 35 }
 36 void work()
 37 {
 38     int i;
 39     for(i=1;i<=n;i++)
 40         if(!dfn[i])
 41             dfs(i);
 42     for(i=1;i<=n;i++)
 43         sz[sccnum[i]]++;
 44     for(i=1;i<=sccc;i++)
 45         if(sz[i]>1)
 46         {
 47             fl=1;
 48             st=i;
 49             break;
 50         }
 51     for(i=1;i<=n;i++)
 52         if(sccnum[i]==st)
 53             ok[i]=1;
 54     for(i=1;i<=n;i++)
 55         if(sccnum[i]==st)
 56         {
 57             st=i;
 58             break;
 59         }
 60 }
 61 }
 62 int main()
 63 {
 64     int i,j,a,b,u;
 65     scanf("%d%d",&n,&m);
 66     for(i=1;i<=m;i++)
 67     {
 68         scanf("%d%d",&a,&b);
 69         e[a].pb(b);
 70     }
 71     Tarjan::work();
 72     if(!fl)    {puts("YES");return 0;}
 73     for(u=st;;)
 74     {
 75         ann.pb(u);
 76         if(ma[u])    break;
 77         ma[u]=ann.size();
 78         for(auto v:e[u])
 79             if(ok[v])
 80             {
 81                 u=v;
 82                 break;
 83             }
 84     }
 85     for(j=ma[ann[ann.size()-1]]-1;j<ann.size()-1;j++)
 86     {
 87         aa=ann[j];bb=ann[j+1];
 88         for(i=1;i<=n;i++)    in[i]=0;
 89         for(i=1;i<=n;i++)
 90             for(auto v:e[i])
 91             {
 92                 if(i==aa&&v==bb)    continue;
 93                 in[v]++;
 94             }
 95         for(i=1;i<=n;i++)
 96             if(!in[i])
 97                 q.push(i);
 98         while(!q.empty())
 99         {
100             u=q.front();q.pop();
101             for(auto v:e[u])
102             {
103                 if(u==aa&&v==bb)    continue;
104                 in[v]--;
105                 if(!in[v])    q.push(v);
106             }
107         }
108         fl=1;
109         for(i=1;i<=n;i++)
110             if(in[i])
111                 fl=0;
112         if(fl)
113         {
114             puts("YES");
115             return 0;
116         }
117     }
118     puts("NO");
119     return 0;
120 }

 

posted @ 2018-05-11 19:35  hehe_54321  阅读(155)  评论(0编辑  收藏  举报
AmazingCounters.com