Educational Codeforces Round 36 (Rated for Div. 2) ---d
阿新 • • 發佈:2018-03-04
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){View Code7 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 }
解法二:
我們先隨便找出一個簡單環,那麽如果有解一定是這個環上的某個邊,枚舉判斷即可。環的大小自然是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