码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 36 (Rated for Div. 2) ---d

时间:2018-03-04 21:22:05      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:一个   include   pre   clu   href   ace   判断   splay   img   

D. Almost Acyclic Graph

 

首先判环可以用拓扑来实现。

暴力解法自然是枚举每一条边,删除,判断是否存在环。

解法一:

对于指向同一个点的边,在拓扑排序中看删除他们事实上是等价的,即那个点入度-1,那么我们枚举所有的点即可。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int inf=1e5+10;
 4 int n,m;
 5 int tot,fi[inf],nxt[inf],to[inf],in[inf];
 6 void link(int x,int y){
 7     to[++tot]=y;nxt[tot]=fi[x];fi[x]=tot;
 8 }
 9 int que[inf],l,r;
10 int tmp[inf];
11 bool topo(){
12     l=1;r=0;
13     for(int i=1;i<=n;i++)tmp[i]=in[i];
14     for(int i=1;i<=n;i++)
15         if(!tmp[i])que[++r]=i;
16     while(l<=r){
17         int u=que[l++];
18         for(int i=fi[u];i;i=nxt[i]){
19             tmp[to[i]]--;
20             if(!tmp[to[i]])que[++r]=to[i];
21         }
22     }
23     return r==n;
24 }
25 int main()
26 {
27     scanf("%d%d",&n,&m);
28     for(int i=1;i<=m;i++){
29         int x,y;
30         scanf("%d%d",&x,&y);
31         link(x,y);
32         in[y]++;
33     }
34     for(int i=1;i<=n;i++){
35         if(!in[i])continue;
36         in[i]--;
37         if(topo()){
38             cout<<"YES"<<endl;
39             return 0;
40         }
41         in[i]++;
42     }
43     cout<<"NO"<<endl;
44     return 0;
45 }
View Code

解法二:

我们先随便找出一个简单环,那么如果有解一定是这个环上的某个边,枚举判断即可。环的大小自然是On级别的。通过dfs可以找出。

注意环不一定存在。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int inf=1e5+10;
 4 int n,m;
 5 int tot,fi[inf],nxt[inf],to[inf],in[inf],flag[inf];
 6 void link(int x,int y){
 7     to[++tot]=y;nxt[tot]=fi[x];fi[x]=tot;
 8 }
 9 int que[inf],l,r;
10 int tmp[inf];
11 bool topo(){
12     l=1;r=0;
13     for(int i=1;i<=n;i++)tmp[i]=in[i];
14     for(int i=1;i<=n;i++)
15         if(!tmp[i])que[++r]=i;
16     while(l<=r){
17         int u=que[l++];
18         for(int i=fi[u];i;i=nxt[i]){
19             if(flag[i])continue;
20             tmp[to[i]]--;
21             if(!tmp[to[i]])que[++r]=to[i];
22         }
23     }
24     return r==n;
25 }
26 int vis[inf];
27 int sta[inf],top;
28 void dfs(int x){
29     vis[x]=1;
30     for(int i=fi[x];i;i=nxt[i]){
31         if(!vis[to[i]]){
32             sta[++top]=i;
33             dfs(to[i]);
34             top--;
35         }
36         if(vis[to[i]]==1){
37             sta[++top]=i;
38             for(int j=1;j<=top;j++){
39                 flag[sta[j]]=1;
40                 in[to[sta[j]]]--;
41                 if(topo()){
42                     cout<<"YES"<<endl;
43                     exit(0);
44                 }
45                 in[to[sta[j]]]++;
46                 flag[sta[j]]=0;
47             }
48             cout<<"NO"<<endl;
49             exit(0);
50         }
51     }
52     vis[x]=-1;
53 }
54 int main()
55 {
56     scanf("%d%d",&n,&m);
57     for(int i=1;i<=m;i++){
58         int x,y;
59         scanf("%d%d",&x,&y);
60         link(x,y);
61         in[y]++;
62     }
63     for(int i=1;i<=n;i++){
64         dfs(i);
65     }
66     cout<<"YES"<<endl;
67     return 0;
68 }
View Code

 

Educational Codeforces Round 36 (Rated for Div. 2) ---d

标签:一个   include   pre   clu   href   ace   判断   splay   img   

原文地址:https://www.cnblogs.com/hyghb/p/8505620.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!