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

 

你可能感兴趣的:(tar)