您的位置:首页 > 其它

UVA -- 10972 RevolC FaeLoN(边双连通)

2015-05-14 20:38 197 查看
题目大意:添加多少条边能使得图变为一个双连通图,图不保证是连通的;

思路分析:求双连通缩点后,对于点数超过一的块,找到叶子结点,连接叶子结点,使其变成一个双连通图;而对于那些只有一个点的块(也就是孤立的点),要连接两条边才能使得其和别的块变成一个整个双连通图,最终答案为((ans2+1+ans1*2)/2)ans2为叶子结点数,ans1为孤立点数。

代码实现:

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
#include<iostream>
//#pragma comment(linker, "/STACK:102400000,102400000")
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define MEM(a) (memset((a),0,sizeof(a)))
#define MEME(a) (memset((a),-1,sizeof(a)))
#define MEMX(a) (memset((a),0x3f,sizeof(a)))
using namespace std;
const int N=1005;
int dfn
,low
,top,bccn,belong
,degree
,tim,n,m;
stack<int> st;
struct Edge{
int v;
Edge *next;
}*head
,e[N*N*2];
void Addedge(int from,int to){
Edge *p=&e[top++];
p->v=to;
p->next=head[from];
head[from]=p;
}
void Tarjan_bcc(int u,int fa){
dfn[u]=low[u]=++tim;
st.push(u);
int v,tmp;
for(Edge *p=head[u];p;p=p->next){
v=p->v;
if(v==fa) continue;
if(!dfn[v]){
Tarjan_bcc(v,u);
low[u]=Min(low[u],low[v]);
if(low[v]>dfn[u]){
++bccn;
do{
tmp=st.top();
st.pop();
belong[tmp]=bccn;
}while(tmp!=v);
}
}else low[u]=Min(low[u],dfn[v]);
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
MEM(head),MEM(dfn),MEM(low),MEM(degree);
bccn=top=tim=0;
int u,v,ans1=0,ans2=0;
while(m--){
scanf("%d%d",&u,&v);
Addedge(u,v);
Addedge(v,u);
}
for(int i=1;i<=n;++i){
if(!dfn[i]){
Tarjan_bcc(i,-1);
++bccn;
int tmp;
while(!st.empty()){
tmp=st.top();
st.pop();
belong[tmp]=bccn;
}
}
}
if(bccn==1){
printf("0\n");
continue;
}
for(int i=1;i<=n;++i)
for(Edge *p=head[i];p;p=p->next)
if(belong[i]!=belong[p->v]) degree[belong[p->v]]++;
for(int i=1;i<=bccn;++i){
if(degree[i]==0) ans1++;
if(degree[i]==1) ans2++;
}
printf("%d\n",(ans2+1+ans1*2)/2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: