CF982F The Meeting Place Cannot Be Changed

题意:给你一张有向图,某人会任意选择起点然后走无穷多步,问是否存在一个点(要求输出)不管他起点在何处怎么走都必经?n<=100005,m<=500005.

 

标程:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=500005;
 4 int cnt,vis[N],n,m,u,v,a[N],tried[N],head[N];
 5 struct node{int to,next;}num[N*2];
 6 void add(int x,int y)
 7 {num[++cnt].to=y;num[cnt].next=head[x];head[x]=cnt;}
 8 int dfs(int x,int ban)
 9 {
10    if (x==ban) return 0;
11    vis[x]=1;
12    for (int i=head[x];i;i=num[i].next)
13        if (!vis[num[i].to]) 
14         {if (dfs(num[i].to,ban)) return 1;}
15       else if (vis[num[i].to]==1){
16           for (int j=1;j<=n;j++)
17             if (vis[j]!=1) tried[j]=1;
18           return 1;
19         }
20     vis[x]=2;
21     return 0;
22 }
23 bool check(int ban)
24 {
25     for (int i=1;i<=n;i++) vis[i]=0;
26     for (int i=1;i<=n;i++)
27       if (!vis[i]) 
28         if (dfs(i,ban)) return 0;
29    return 1;
30 }
31 int main()
32 {
33     srand(time(NULL)); 
34     scanf("%d%d",&n,&m);
35     for (int i=1;i<=m;i++) scanf("%d%d",&u,&v),add(u,v);//注意单向连边 
36     for (int i=1;i<=n;i++) a[i]=i;
37     random_shuffle(a+1,a+n+1);
38     for (int i=1;i<=n;i++)
39     {
40         if ((double)clock()/CLOCKS_PER_SEC>0.95) break;
41         if (!tried[a[i]])
42           if (check(a[i])) return printf("%d\n",a[i]),0;
43     }
44     puts("-1");
45     return 0;
46 }

 

易错点:1.注意单向连边。

2.random_shuffle可以有效防卡,要srand。

 

题解: dfs找环

枚举要选择的点,dfs找是否存在一条带环的不经过该点的路径,如果不存在,那么该点为答案;如果存在,那么该路径之外的点一定不可能是答案,标记掉不找。加上卡时就可以过掉。

转载于:https://www.cnblogs.com/Scx117/p/9070363.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值