首先判环可以用拓扑来实现。
暴力解法自然是枚举每一条边,删除,判断是否存在环。
解法一:
对于指向同一个点的边,在拓扑排序中看删除他们事实上是等价的,即那个点入度-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 }
解法二:
我们先随便找出一个简单环,那么如果有解一定是这个环上的某个边,枚举判断即可。环的大小自然是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 }