http://codeforces.com/contest/915/problem/D
【分析】
赛时没有A掉这道题。之后看群里讨论说,找到一个环,然后在这个环上dfs,枚举删掉遍历到的边,再拓扑排序判环。
今天写了个代码不知道为啥奇迹般的A了。直接dfs这个图,枚举删除遍历到的边 同时判环。
【代码】
#include<bits/stdc++.h>
using namespace std;
struct NODE{
int from,to;
int next;
NODE(int f=0,int t=0,int ne=0){
from=f;to=t;next=ne;
}
}edge[220000];
int head[520];
int inn[520],in[520];//入度
int vis[520];
int n,m;
int flag=0;
int check()//拓扑排序判环
{
int q[520],tail=0;
for(int i=1;i<=n;i++)//入度为0的点入队
if(!in[i])
q[tail++]=i;
for(int i=0;i<tail;i++)
{
int s=q[i];//此起点的边全删
for(int j=head[s];j!=-1;j=edge[j].next)
{
in[edge[j].to]--;
if(!in[edge[j].to])//新的入度为0的点
{
q[tail++]=edge[j].to;
}
}
}
return n==tail;
}
void dfs(int u)
{
if(flag)return;
for(int k=head[u];~k;k=edge[k].next)if(!vis[edge[k].to])
{
int t=edge[k].to;
vis[t]=1;
for(int i=1;i<=n;i++)in[i]=inn[i];
in[t]--;
if(check()){flag=1;break;}
dfs(t);
}
}
int main()
{
while(cin>>n>>m)
{
memset(head,-1,sizeof(head));
memset(in,0,sizeof(in));
for(int i=0;i<m;i++)
{
int f,t;
scanf("%d%d",&f,&t);
in[t]++;
inn[t]++;
edge[i]=NODE(f,t,head[f]);
head[f]=i;//链式前向星
}
memset(vis,0,sizeof(vis));
flag=0;
for(int i=1;i<=n;i++)dfs(i);
if(flag)printf("Yes\n");
else printf("No\n");
}
return 0;
}