【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
null