POJ3352Road Construction(无向图强连通)

http://poj.org/problem?id=3352

无向图强连通分量缩点 知道一个等式:

若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么

至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<stack>

 5 #include<algorithm>

 6 #include<stdlib.h>

 7 using namespace std;

 8 #define N 1010

 9 #define M 2010

10 struct node

11 {

12     int u,v,next;

13 }edge[M];

14 stack<int>s;

15 int head[N],pre[N],low[N],sccno[N],scc,dep,t,de[N],vis[N],w[N][N];

16 void init()

17 {

18     t = 0;

19     memset(head,-1,sizeof(head));

20     scc=0;dep=0;

21     memset(sccno,0,sizeof(sccno));

22     memset(low,0,sizeof(low));

23     memset(pre,0,sizeof(pre));

24     memset(vis,0,sizeof(vis));

25 }

26 void add(int u,int v)

27 {

28     edge[t].u = u;

29     edge[t].v = v;

30     edge[t].next = head[u];

31     head[u] = t++;

32 }

33 void dfs(int u,int fa)

34 {

35     low[u] = pre[u] = ++dep;

36     s.push(u);

37     for(int i = head[u] ; i!=-1 ; i = edge[i].next)

38     {

39         int v = edge[i].v;

40         if(v==fa) continue;

41         if(!pre[v])

42         {

43             dfs(v,u);

44             low[u] = min(low[u],low[v]);

45         }

46         else if(!sccno[v])

47         low[u] = min(low[u],pre[v]);

48     }

49     if(low[u]==pre[u])

50     {

51         scc++;

52         for(;;)

53         {

54             int x = s.top();s.pop();

55             sccno[x] = scc;

56             if(x==u) break;

57         }

58     }

59 }

60 int main()

61 {

62     int i,n,m,kk=0;

63     char str[100];

64     while(cin>>n>>m)

65     {

66         kk++;init();

67         memset(w,0,sizeof(w));

68         memset(de,0,sizeof(de));

69         int a,b;

70         while(m--)

71         {

72             scanf("%d%d",&a,&b);

73             add(a,b);add(b,a);

74         }

75         dfs(1,1);

76         for(i = 0 ; i < t  ; i++)

77         {

78             int u = edge[i].u,v = edge[i].v;

79             if(!w[u][v]&&sccno[u]!=sccno[v])

80             {

81                 w[u][v]  = w[v][u]= 1;

82                 de[sccno[u]]++;

83                 de[sccno[v]]++;

84             }

85         }

86         int num=0;

87         for(i = 1; i <= scc ; i++)

88         if(de[i]==1) num++;

89         cout<<(num+1)/2<<endl;

90     }

91     return 0;

92 }
View Code

 

你可能感兴趣的:(struct)