[hdu1269]城堡迷宫<tarjan强连通分量>

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269

tarjan算法是oi里很常用的一个算法,在理解方面需要多下一些功夫,如果不行直接记模板也行,因为tarjan主要是细节不好理解。。。

我目前就是记得模板

然后这道题是个tarjan的裸题,就是把tarjan的模板打出来就可以A了

虽然我还是WA了很多次,最后总结原因发现是因为多组输入的原因,多组输入的时候n和m可能会单独存在0的情况(不同时为0),而我的初始程序就是只要有零就跳出,然后成功WA了多次(这是何等的窝草啊)

所以这题其实就是找下强联通个数,如果是一个就可以输出yes,否则输出no

当然你也可以主动去优化,优化方式就是当出现第一个强联通时不包括所有点就可以输出no然后exit(0)了

虽然优不优化这题都可以顺利通过

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<stack>
 7 #include<queue>
 8 #include<cstdlib> 
 9 #define maxn 100005
10 using namespace std;
11 
12 struct edge{
13     int u,v,nxt;
14 }e[maxn];
15 int n,m,ans,head[maxn],dfn[maxn],low[maxn],belong[maxn];
16 
17 int read(){
18     int xx=0,ff=1;char ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')ff=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
21     return xx*ff;
22 }
23 
24 int tot;
25 void adde(int u,int v){
26     e[tot]=(edge){u,v,head[u]};
27     head[u]=tot++;
28 }
29 
30 stack<int>s;
31 int num;
32 void tarjan(int x){
33     num++;
34     dfn[x]=num;low[x]=num;
35     s.push(x);
36     for(int i=head[x];i!=-1;i=e[i].nxt){
37         int v=e[i].v;
38         if(dfn[v]==0){
39             tarjan(v);
40             low[x]=min(low[x],low[v]);
41         }else{
42             if(!belong[v]){low[x]=min(low[x],dfn[v]);}
43         }            
44     }
45     if(dfn[x]==low[x]){
46         ans++;
47         int u=s.top();
48         while(u!=x){
49             belong[u]=ans;
50             s.pop();
51             u=s.top();
52         }belong[u]=ans;s.pop();
53     }
54 }
55 
56 int main(){
57     while(1){
58         n=read();m=read();
59         if(n==0&&m==0)return 0;
60         tot=0;num=0;ans=0;
61         while(!s.empty())s.pop();
62         memset(dfn,0,sizeof(dfn));
63         memset(belong,0,sizeof(belong));
64         memset(low,0,sizeof(low));
65         memset(head,-1,sizeof(head));    
66         for(int i=1;i<=m;i++){
67             int u,v;
68             u=read();v=read();
69             adde(u,v);
70         }    
71         for(int i=1;i<=n;i++){
72             if(!dfn[i]){tarjan(i);}
73         }
74         if(ans==1)printf("Yes\n");
75         else printf("No\n");    
76     }
77 }
View Code

【总结】

tarjan的理解比较难的地方就是他的low数组和low数组的值的变化,建议多结合图例去理解

转载于:https://www.cnblogs.com/Danzel-Aria233/p/7767677.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值