标签:
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