loj 1026( tarjan + 输出割边 )

题目链接:http://lightoj.com/volume_showproblem.php?problem=1026

思路:Tarjan 算法简单应用。割边的特点:low[v]>dfn[u](v是u的子节点)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 #define MAXN 22222
 8 
 9 struct Edge{
10     int v,next;
11 }edge[MAXN*22];
12 
13 int n,NE;
14 int head[MAXN];
15 
16 void Insert(int u,int v)
17 {
18     edge[NE].v=v;
19     edge[NE].next=head[u];
20     head[u]=NE++;
21 }
22 
23 int cnt,bcc_count;
24 int low[MAXN],dfn[MAXN];
25 bool mark[MAXN];
26 vector<pair<int,int> >bridge;
27 
28 void Tarjan(int u,int father)
29 {
30     int flag=0;
31     low[u]=dfn[u]=++cnt;
32     mark[u]=true;
33     for(int i=head[u];i!=-1;i=edge[i].next){
34         int v=edge[i].v;
35         if(v==father&&!flag){ flag=1;continue; }
36         if(dfn[v]==0){
37             Tarjan(v,u);
38             low[u]=min(low[u],low[v]);
39             if(low[v]>dfn[u]){
40                 bridge.push_back(make_pair(min(u,v),max(u,v)));
41             }
42         }else if(mark[v]){
43             low[u]=min(low[u],dfn[v]);
44         }
45     }
46 }
47 
48 int cmp(const pair<int,int>p,const pair<int,int>q)
49 {
50     if(p.first!=q.first)return p.first<q.first;
51     return p.second<q.second;
52 }
53 
54 int main()
55 {
56     int _case,u,v,x,t=1;
57     scanf("%d",&_case);
58     while(_case--){
59         scanf("%d",&n);
60         NE=0;
61         memset(head,-1,sizeof(head));
62         for(int i=0;i<n;i++){
63             scanf("%d (%d)",&u,&x);
64             while(x--){
65                 scanf("%d",&v);
66                 Insert(u,v);
67             }
68         }
69         bridge.clear();
70         cnt=bcc_count=0;
71         memset(dfn,0,sizeof(dfn));
72         memset(mark,false,sizeof(mark));
73         for(int i=0;i<n;i++)if(dfn[i]==0)Tarjan(i,-1);
74         printf("Case %d:\n",t++);
75         printf("%d critical links\n",(int)bridge.size());
76         sort(bridge.begin(),bridge.end(),cmp);
77         for(int i=0;i<(int)bridge.size();i++){
78             printf("%d - %d\n",bridge[i].first,bridge[i].second);
79         }
80     }
81     return 0;
82 }
View Code

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值