【POJ3352】Road Construction(边双联通分量)

题意:给一个无向图,问最少添加多少条边后能使整个图变成双连通分量。

思路:双连通分量缩点,缩点后给度为1的分量两两之间连边,要连(ans+1) div 2条

         low[u]即为u所在的分量编号,flag=0,1,2表示没搜过,没搜完,搜完了

POJ上pascal编译器出问题了不管怎么交都CE

这次写的 应该能处理重边

 1 var head,vet,next,flag,dfn,low,fan,de:array[0..10000]of longint;
 2     n,m,i,e,v,ans,x,y,tot,time:longint;
 3 
 4 procedure add(a,b:longint);
 5 begin
 6  inc(tot);
 7  next[tot]:=head[a];
 8  vet[tot]:=b;
 9  head[a]:=tot;
10 end;
11 
12 function min(x,y:longint):longint;
13 begin
14  if x<y then exit(x);
15  exit(y);
16 end;
17 
18 procedure dfs(u,le:longint);
19 var e,v:longint;
20 begin
21  flag[u]:=1;
22  inc(time); dfn[u]:=time; low[u]:=time;
23  e:=head[u];
24  while e<>0 do
25  begin
26   v:=vet[e];
27   if e=fan[le] then
28   begin
29    e:=next[e];
30    continue;
31   end;
32   if flag[v]=0 then
33   begin
34    dfs(v,e);
35    low[u]:=min(low[u],low[v]);
36   end
37    else if flag[v]=1 then low[u]:=min(low[u],dfn[v]);
38   e:=next[e];
39  end;
40  flag[u]:=2;
41 end;
42 
43 begin
44 
45  for i:=0 to 2000 do
46    if i mod 2=1 then fan[i]:=i+1
47     else fan[i]:=i-1;
48  while not eof do
49  begin
50   readln(n,m);
51   if (n=0)and(m=0) then break;
52   fillchar(head,sizeof(head),0);
53   fillchar(low,sizeof(low),0);
54   fillchar(de,sizeof(de),0);
55   fillchar(flag,sizeof(flag),0);
56   tot:=0; time:=0;
57   for i:=1 to m do
58   begin
59    read(x,y);
60    add(x,y);
61    add(y,x);
62   end;
63   for i:=1 to n do
64    if flag[i]=0 then dfs(i,0);
65   for i:=1 to n do
66   begin
67    e:=head[i];
68    while e<>0 do
69    begin
70     v:=vet[e];
71     if low[v]<>low[i] then inc(de[low[i]]);
72     e:=next[e];
73    end;
74   end;
75   ans:=0;
76   for i:=1 to n do
77    if de[i]=1 then inc(ans);
78   writeln((ans+1) div 2);
79  end;
80 
81 end.

这个是去年写的那时候AC了 好像不能处理重边

 1 var de,low,next,vet,head,flag,dfn:array[1..10000]of longint;
 2     n,m,tot,x,y,i,e,v,leaf,time:longint;
 3 
 4 function min(x,y:longint):longint;
 5 begin
 6  if x<y then exit(X);
 7  exit(y);
 8 end;
 9 
10 procedure add(a,b:longint);
11 begin
12  inc(tot);
13  next[tot]:=head[a];
14  vet[tot]:=b;
15  head[a]:=tot;
16 end;
17 
18 procedure dfs(u,fa:longint);
19 var e,v:longint;
20 begin
21  inc(time);
22  dfn[u]:=time; low[u]:=time;
23  flag[u]:=1;
24  e:=head[u];
25  while e<>0 do
26  begin
27   v:=vet[e];
28   if v=fa then
29   begin
30    e:=next[e];
31    continue;
32   end;
33   if flag[v]=0 then
34   begin
35    dfs(v,u);
36    low[u]:=min(low[u],low[v]);
37   end
38    else if flag[v]=1 then low[u]:=min(low[u],dfn[v]);
39   e:=next[e];
40  end;
41  flag[u]:=2;
42 end;
43 
44 begin
45 
46  while not eof do
47  begin
48   readln(n,m);
49   if (n=0)and(m=0) then break;
50   fillchar(head,sizeof(head),0);
51   tot:=0;
52   for i:=1 to m do
53   begin
54    readln(x,y);
55    add(x,y);
56    add(y,x);
57   end;
58   fillchar(dfn,sizeof(dfn),0);
59   fillchar(de,sizeof(de),0);
60   fillchar(flag,sizeof(flag),0);
61   time:=0;
62   for i:=1 to n do
63    if flag[i]=0 then dfs(i,i);
64   for i:=1 to n do
65   begin
66    e:=head[i];
67    while e<>0 do
68    begin
69     v:=vet[e];
70     if low[i]<>low[v] then inc(de[low[i]]);
71     e:=next[e];
72    end;
73   end;
74   leaf:=0;
75   for i:=1 to n do
76    if de[i]=1 then inc(leaf);
77   writeln((leaf+1) div 2);
78  end;
79 
80 end.

 UPD(2018.10.18):C++

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second
 19 #define MP make_pair
 20 #define N   15000
 21 #define M   6100000
 22 #define eps 1e-8
 23 #define pi  acos(-1)
 24 #define oo  1e9
 25 
 26 int head[N],vet[N],nxt[N],flag[N],dfn[N],low[N],fan[N],d[N],
 27     tot,tim;
 28      
 29 void add(int a,int b)
 30 {
 31     nxt[++tot]=head[a];
 32     vet[tot]=b;
 33     head[a]=tot;
 34 }
 35 
 36 void dfs(int u,int le)
 37 {
 38     flag[u]=1;
 39     dfn[u]=low[u]=++tim;
 40     int e=head[u];
 41     while(e)
 42     {
 43         int v=vet[e];
 44         if(e==fan[le])
 45         {
 46             e=nxt[e];
 47             continue;
 48         }
 49         if(!flag[v])
 50         {
 51             dfs(v,e);
 52             low[u]=min(low[u],low[v]);
 53         }
 54          else if(flag[v]==1) low[u]=min(low[u],dfn[v]);
 55         e=nxt[e];
 56     }
 57     flag[u]=2;
 58 }
 59 
 60 int main()
 61 {
 62     freopen("poj3352.in","r",stdin);
 63     freopen("poj3352.out","w",stdout);
 64     for(int i=0;i<=2000;i++) 
 65      if(i&1) fan[i]=i+1;
 66       else fan[i]=i-1;
 67     int n,m;
 68     while(scanf("%d%d",&n,&m)!=EOF)
 69     {
 70         memset(head,0,sizeof(head));
 71         memset(low,0,sizeof(low));
 72         memset(d,0,sizeof(d));
 73         memset(flag,0,sizeof(flag));
 74         tot=tim=0;
 75         for(int i=1;i<=m;i++)
 76         {
 77             int x,y;
 78             scanf("%d%d",&x,&y);
 79             add(x,y);
 80             add(y,x);
 81         }
 82         for(int i=1;i<=n;i++)
 83          if(flag[i]==0) dfs(i,0);
 84         for(int i=1;i<=n;i++)
 85         {
 86             int e=head[i];
 87             while(e)
 88             {
 89                 int v=vet[e];
 90                 if(low[v]!=low[i]) d[low[i]]++;
 91                 e=nxt[e];
 92             }
 93         } 
 94         int ans=0;
 95         for(int i=1;i<=n;i++)
 96          if(d[i]==1) ans++;
 97         printf("%d\n",(ans+1)/2); 
 98     }
 99     return 0;
100 }
101         
102         

 

posted on 2016-09-26 20:57  myx12345  阅读(186)  评论(0编辑  收藏  举报

导航