您的位置:首页 > 其它

GYM 100712 H.Bridges(边双连通分量)

2017-03-13 17:13 239 查看
Description

给出一个n个点m条边的无向图,要求新加一条边使得加完边后的新图的桥最少

Input

第一行一整数T表示用例组数,每组用例首先输入两整数n和m分别表示点数和边数,之后m行每行两个整数u和v表示u和v之间有一条边(1<=T<=64,3<=n<=1e5,n-1<=m<=1e5)

Output

输出加一条边后最少的桥数

Sample Input



Sample Output

1

0

Solution

Tarjan缩点,对缩完点的树求一遍直径,连接直径的两个端点减少的桥数最多,原先的桥数减去直径长度即为答案

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 111111
#define maxm 222222
struct Edge
{
int to,next;
bool flag;//标记是否是桥
}edge[maxm];
int head[maxn],tot;
int low[maxn],dfn[maxn],stack[maxn],belong[maxn];//belong数组的值是1~block
int index,top;
int block;//边双连通块数
bool instack[maxn];
int bridge;//桥的数目
void addedge(int u,int v)
{
edge[tot].to=v,edge[tot].next=head[u],edge[tot].flag=0;
head[u]=tot++;
}
void Tarjan(int u,int pre)
{
int v;
low[u]=dfn[u]=++index;
stack[top++]=u;
instack[u]=1;
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].flag=1;
edge[i^1].flag=1;
}
}
else if(instack[v]&&low[u]>dfn[v])
low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
block++;
do
{
v=stack[--top];
instack[v]=0;
belong[v]=block;
}
while(v!=u);
}
}
void init()
{
memset(dfn,0,sizeof(dfn));
memset(stack,0,sizeof(stack));
index=block=top=bridge=tot=0;
memset(head,-1,sizeof(head));
}
int T,n,m,e[maxn][2],deep,pos;
int dfs(int u,int fa,int cnt)
{
if(cnt>deep)deep=cnt,pos=u;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa)continue;
dfs(v,u,cnt+1);
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&e[i][0],&e[i][1]);
addedge(e[i][0],e[i][1]),addedge(e[i][1],e[i][0]);
}
Tarjan(1,1);
init();
int ans=0;
for(int i=1;i<=m;i++)
{
int u=belong[e[i][0]],v=belong[e[i][1]];
if(u!=v)
ans++,addedge(u,v),addedge(v,u);
}
deep=0;
dfs(1,1,0);
deep=0;
dfs(pos,pos,0);
printf("%d\n",ans-deep);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: