uva 610(tarjan的应用)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23727

思路:首先是Tarjan找桥,对于桥,只能是双向边,而对于同一个连通分量而言,只要重新定向为同一个方向即可。

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值