您的位置:首页 > 其它

Network---3694poj(桥)

2015-08-07 08:41 274 查看
题目链接

题意:

有n个电脑1-n,m个连接,由于可能存在一些桥,如果这些桥出现了问题,那么会导致一些电脑之间无法连接,

所以建立链接Q次,每次链接a和b电脑,求链接ab后还存在几个桥;

如果说在ab之间建立连接, a和b的最近祖先(LCA),那么从a到LCA之间和b到LCA之间的桥都将不在是桥了

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <cstring>
using namespace std;
#define INF 0xfffffff
#define N 101000
int low
, dfn
, f
, bridge
;
//bridge[i] 是表示i和f[i]之间的路是否是桥;值为1的时候是桥;
vector<vector<int> > G;
int n, Time, m, nbridge;

void Init()
{
G.clear();
G.resize(n+1);
Time = nbridge = 0;
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(f, 0, sizeof(f));
}

void Tarjan(int u, int father)
{
f[u] = father;
dfn[u] = low[u] = ++Time;
int len = G[u].size(), v;
for(int i=0; i<len; i++)
{
v = G[u][i];
if(!dfn[v])
{
Tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u])
{
bridge[v]++;
nbridge++;
}
}
else if(v!=father)//避免找回自己的父节点;
{
low[u] = min(low[u], dfn[v]);
}
}
}

void LCA(int a, int b)
{
if( a == b )
return ;
if(dfn[a] < dfn[b])
{
if(bridge[b]==1)
{
bridge[b] = 0;
nbridge--;
}
LCA(a, f[b]);
}
else
{
if(bridge[a]==1)
{
bridge[a] = 0;
nbridge--;
}
LCA(f[a], b);
}
}

int main()
{
int t=0, a, b, Q;
while(scanf("%d %d", &n, &m), n+m)
{
Init();
while(m--)
{
scanf("%d %d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
Tarjan(1,0);
printf("Case %d:\n", ++t);
scanf("%d", &Q);
while(Q--)
{
scanf("%d%d", &a,&b);
LCA(a,b);
printf("%d\n",nbridge);
}
printf("\n");
}
return 0;
}


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