您的位置:首页 > 其它

poj 3353 Road Construction tarjan 边双联通分支 缩点+结论

2013-08-12 02:23 423 查看
题意:一个连通的无向图,求至少需要添加几条边,救能保证删除任意一条边,图仍然是连通的。

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

思路:边的双连通图。其实就是要求至少添加几条边,可以使整个图成为一个边双连通图。用tarjan算法(求割点割边)求出low数组,这里可以简化,然 后依据“low相同的点在一个边连通分量中”,缩点之后构造成树(这里可以直接利用low[]数组,low[i]即为第i节点所在的连通分量的标号)。求 出树中出度为1的节点数left,答案即为(leaf+1)/2。

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <stack>
#define loop(s,i,n) for(i = s;i < n;i++)
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn = 1005;
using namespace std;
int dfn[maxn],low[maxn],belong[maxn],dfsclock,bcc_cnt;
vector<int>g[maxn];
vector<int>ng[maxn];
struct edge
{
int u,v,w;
};
stack<edge> st;
vector<edge> edges;
stack<int>s;
void init(int n)
{
int i;
for(i = 0; i <= n; i++)
g[i].clear();
edges.clear();
return ;
}
int in[maxn];
void tarjan(int u,int pre)
{
int v,i,j;
dfn[u] = low[u] = ++dfsclock;
s.push(u);
loop(0,i,g[u].size())
{
v = g[u][i];

if(v != pre)
{
if(!dfn[v])//保证是树枝边
{
tarjan(v,u);

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

}
else if(dfn[v] < low[u])
low[u] = dfn[v];
}

}
if(low[u] ==dfn[u])
{
bcc_cnt++;
int t;
do
{

t = s.top();
s.pop();
belong[t] = bcc_cnt;
}
while(t != u);
}
}

void find_bcc(int n)
{
int i;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));

memset(belong,0,sizeof(belong));
while(!s.empty())s.pop();
dfsclock = bcc_cnt = 0;
loop(1,i,n)
if(!dfn[i]) tarjan(i,-1);
// puts("yes");
// printf("%d  """"""\n",bcc_cnt);
}

int main()
{
int m,n;

while(~scanf("%d %d",&n,&m))
{
init(n);
int i,j;
for(i = 1; i <= m; i++)
{
int u,v;
struct edge e;
scanf("%d %d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
e.u = u;
e.v = v;
edges.push_back(e);
}

find_bcc(n);
cl(in,0);
struct edge e;
for(j = 0; j < edges.size(); j++)
{
e = edges[j];
if(belong[e.v] != belong[e.u])
{
in[belong[e.v]]++;
in[belong[e.u]]++;
}
}
int leaf;
leaf = 0;
// cout<<bcc_cnt<<endl;
for(i = 1; i <= bcc_cnt; i++)
if(in[i]==1)
leaf++;

cout<<(leaf+1)/2<<endl;
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: