zoukankan      html  css  js  c++  java
• # 【POJ 3177】Redundant Paths（边双连通分量）

求出每个边双连通分量缩点后的度，度为1的点即叶子节点。原图加上（leaf+1）/2条边即可变成双连通图。

```#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>

using namespace std;
const int N = 5010;
const int M = 10010;
struct Edge
{
int to,next;
bool cut;
}edge[M];
int Low[N],DFN[N],Stack[N],Belong[N];
int Index,top;
int block;
bool Instack[N];
int bridge;
{
edge[tot].cut=false;
}
void Tarjan(int u,int pre)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u];~i;i = edge[i].next)
{
v = edge[i].to;
if(v == pre)continue;
if( !DFN[v] )
{
Tarjan(v,u);
if( Low[u] > Low[v] )Low[u] = Low[v];
if(Low[v] > DFN[u])//桥
{
bridge++;
edge[i].cut = true;
edge[i^1].cut = true;
}
}
else if(Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
if(Low[u] == DFN[u])
{
block++;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = block;
}
while( v != u);
}
}
int du[N];//缩点后形成树，每个点的度数
void solve(int n)
{
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof Instack);
Index = block = top = 0;
Tarjan(1,0);
int ans = 0;
memset(du,0,sizeof(du));
for(int i = 1;i <= n;i++)
for(int j = head[i];~j;j = edge[j].next)
if(edge[j].cut)
du[Belong[i]]++;
for(int i = 1;i <= block;i++)
if(du[i]==1)
ans++;
printf("%d
",(ans+1)/2);
}
void init()
{
tot = 0;
}
int main()
{
int n,m;
int u,v;
while(scanf("%d%d",&n,&m)==2)
{
init();
while(m--)
{
scanf("%d%d",&u,&v);
}
solve(n);
}
return 0;
}```

• 相关阅读:
常用Linux命令
SQL必知必会-笔记