标签:
Warm up
Description
Input
Output
Sample Input
Sample Output
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int maxn = 200100;
struct Edge{
int from,to,dist,next;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){}
}edges[maxn*10];
int head[maxn], tot;
int dfs_clock, dfn[maxn], brinum;
int Stack[maxn], instack[maxn], top, ebccno[maxn], ebcc_cnt;
int deg[maxn];
vector<int>G[maxn];
void init(){
tot = 0;
brinum = dfs_clock = 0;
top = 0;
ebcc_cnt = 0;
memset(deg,0,sizeof(deg));
memset(head,-1,sizeof(head));
}
void AddEdge(int _u,int _v){
edges[tot] = Edge(_v,head[_u]);
head[_u] = tot++;
}
int dfs(int u,int fa){
int lowu = dfn[u] = ++dfs_clock;
Stack[++top] = u;
// instack[u] = 1;
for(int i = head[u]; i != -1; i = edges[i].next){
int v = edges[i].to;
if(!dfn[v]){
int lowv = dfs(v,i);
lowu = min(lowu,lowv);
if(lowv > dfn[u]){
brinum++;
}
}else if(dfn[v] < dfn[u] && (fa^1) != i){//这里用边的编号来标记是否是同一条边的回边
lowu = min(lowu,dfn[v]);
}
}
if(dfn[u] == lowu){ //找到一个边双连通分量
ebcc_cnt++;
for(;;){
int v = Stack[top--];
// instack[v] = 0;
ebccno[v] = ebcc_cnt; //给每个点划分一个分量标号
if(u == v){
break;
}
}
}
// low[u] = lowu;
return lowu;
}
void find_ebcc(int n){
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
for(int i = 1; i <= n; i++){
if(!dfn[i]){
dfs(i,-1);
}
}
}
int pos, Maxd;
void dfs1(int u,int dep,int fa){ //求树的直径
if(dep > Maxd){
Maxd = dep;
pos = u;
}
for(int i = 0; i < G[u].size(); i++){
int v = G[u][i];
if(fa == v){ continue; }
dfs1(v,dep+1,u);
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){
init();
for(int i = 0; i <= n; i++){
G[i].clear();
}
int a,b;
for(int i = 0; i < m; i++){
scanf("%d%d",&a,&b);
AddEdge(a,b);
AddEdge(b,a);
}
find_ebcc(n);
for(int i = 1; i <= n; i++){
for(int j = head[i]; j != -1; j = edges[j].next){
int v = edges[j].to;
if(ebccno[i] != ebccno[v]){ //重新构图,形成树
G[ebccno[i]].push_back(ebccno[v]);
}
}
}
pos = 1, Maxd = 0;
dfs1(1,0,-1);
int st = pos; Maxd = 0;
dfs1(pos,0,-1);
printf("%d\n",brinum - Maxd);
}
return 0;
}
HDU 4612——Warm up——————【边双连通分量、树的直径】
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4943573.html