【POJ3352】Road Construction(边双联通分量)
2016-09-26 20:57
351 查看
题意:给一个无向图,问最少添加多少条边后能使整个图变成双连通分量。
思路:双连通分量缩点,缩点后给度为1的分量两两之间连边,要连(ans+1) div 2条
low[u]即为u所在的分量编号,flag=0,1,2表示没搜过,没搜完,搜完了
POJ上pascal编译器出问题了不管怎么交都CE
这次写的 应该能处理重边
var head,vet,next,flag,dfn,low,fan,de:array[0..10000]of longint; n,m,i,e,v,ans,x,y,tot,time:longint; procedure add(a,b:longint); begin inc(tot); next[tot]:=head[a]; vet[tot]:=b; head[a]:=tot; end; function min(x,y:longint):longint; begin if x<y then exit(x); exit(y); end; procedure dfs(u,le:longint); var e,v:longint; begin flag[u]:=1; inc(time); dfn[u]:=time; low[u]:=time; e:=head[u]; while e<>0 do begin v:=vet[e]; if e=fan[le] then begin e:=next[e]; continue; end; if flag[v]=0 then begin dfs(v,e); low[u]:=min(low[u],low[v]); end else if flag[v]=1 then low[u]:=min(low[u],dfn[v]); e:=next[e]; end; flag[u]:=2; end; begin for i:=0 to 2000 do if i mod 2=1 then fan[i]:=i+1 else fan[i]:=i-1; while not eof do begin readln(n,m); if (n=0)and(m=0) then break; fillchar(head,sizeof(head),0); fillchar(low,sizeof(low),0); fillchar(de,sizeof(de),0); fillchar(flag,sizeof(flag),0); tot:=0; time:=0; for i:=1 to m do begin read(x,y); add(x,y); add(y,x); end; for i:=1 to n do if flag[i]=0 then dfs(i,0); for i:=1 to n do begin e:=head[i]; while e<>0 do begin v:=vet[e]; if low[v]<>low[i] then inc(de[low[i]]); e:=next[e]; end; end; ans:=0; for i:=1 to n do if de[i]=1 then inc(ans); writeln((ans+1) div 2); end; end.
这个是去年写的那时候AC了 好像不能处理重边
var de,low,next,vet,head,flag,dfn:array[1..10000]of longint; n,m,tot,x,y,i,e,v,leaf,time:longint; function min(x,y:longint):longint; begin if x<y then exit(X); exit(y); end; procedure add(a,b:longint); begin inc(tot); next[tot]:=head[a]; vet[tot]:=b; head[a]:=tot; end; procedure dfs(u,fa:longint); var e,v:longint; begin inc(time); dfn[u]:=time; low[u]:=time; flag[u]:=1; e:=head[u]; while e<>0 do begin v:=vet[e]; if v=fa then begin e:=next[e]; continue; end; if flag[v]=0 then begin dfs(v,u); low[u]:=min(low[u],low[v]); end else if flag[v]=1 then low[u]:=min(low[u],dfn[v]); e:=next[e]; end; flag[u]:=2; end; begin while not eof do begin readln(n,m); if (n=0)and(m=0) then break; fillchar(head,sizeof(head),0); tot:=0; for i:=1 to m do begin readln(x,y); add(x,y); add(y,x); end; fillchar(dfn,sizeof(dfn),0); fillchar(de,sizeof(de),0); fillchar(flag,sizeof(flag),0); time:=0; for i:=1 to n do if flag[i]=0 then dfs(i,i); for i:=1 to n do begin e:=head[i]; while e<>0 do begin v:=vet[e]; if low[i]<>low[v] then inc(de[low[i]]); e:=next[e]; end; end; leaf:=0; for i:=1 to n do if de[i]=1 then inc(leaf); writeln((leaf+1) div 2); end; end.
UPD(2018.10.18):C++
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<iostream> #include<algorithm> #include<map> #include<set> #include<queue> #include<vector> using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef pair<int,int> PII; typedef vector<int> VI; #define fi first #define se second #define MP make_pair #define N 15000 #define M 6100000 #define eps 1e-8 #define pi acos(-1) #define oo 1e9 int head ,vet ,nxt ,flag ,dfn ,low ,fan ,d , tot,tim; void add(int a,int b) { nxt[++tot]=head[a]; vet[tot]=b; head[a]=tot; } void dfs(int u,int le) { flag[u]=1; dfn[u]=low[u]=++tim; int e=head[u]; while(e) { int v=vet[e]; if(e==fan[le]) { e=nxt[e]; continue; } if(!flag[v]) { dfs(v,e); low[u]=min(low[u],low[v]); } else if(flag[v]==1) low[u]=min(low[u],dfn[v]); e=nxt[e]; } flag[u]=2; } int main() { freopen("poj3352.in","r",stdin); freopen("poj3352.out","w",stdout); for(int i=0;i<=2000;i++) if(i&1) fan[i]=i+1; else fan[i]=i-1; int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(head,0,sizeof(head)); memset(low,0,sizeof(low)); memset(d,0,sizeof(d)); memset(flag,0,sizeof(flag)); tot=tim=0; for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(int i=1;i<=n;i++) if(flag[i]==0) dfs(i,0); for(int i=1;i<=n;i++) { int e=head[i]; while(e) { int v=vet[e]; if(low[v]!=low[i]) d[low[i]]++; e=nxt[e]; } } int ans=0; for(int i=1;i<=n;i++) if(d[i]==1) ans++; printf("%d\n",(ans+1)/2); } return 0; }
相关文章推荐
- POJ 3352|Road Construction|边双联通分量|Tarjan
- POJ 3352 Road Construction&& POJ 3177 Redundant Paths 双联通分量
- 【POJ 3352】 Road Construction(边联通分量入门)
- 边双联通问题求解(构造边双连通图)POJ3352(Road Construction)
- POJ 3352 Road Construction 边双联通分量
- POJ3352 Road Construction【边双联通分量】【Tarjan】
- Road Construction+求双联通分量、割点、桥+POJ
- POJ 3352 Road Construction 双联通分量 难度:1
- poj 3352 Road Construction(双联通)
- poj3352 Road Construction 缩点
- poj3352 Road Construction 边双连通分量tarjan算法
- poj 3353 Road Construction tarjan 边双联通分支 缩点+结论
- poj3352 Road Construction (双连通)
- poj3352 边-双联通分量
- 【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题
- 【BZOJ2730】【codevs1996】矿场建设,点双联通分量
- UVA 1108 Mining Your Own Business(双联通分量)
- tanjan算法求强联通分量
- 点双联通分量和边双联通分量小结
- 【图论】强联通分量