1. 程式人生 > >Educational Codeforces Round 36 (Rated for Div. 2) ---d

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

continue void 枚舉 nal HR spl %d 大小 log

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