标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4612
4 4 1 2 1 3 1 4 2 3 0 0
0
/** hdu4612 连通性,求树的直径,加一边求最少桥 题目大意:给定一个无向连通图加上一条边后所得到的图所含的桥的数目最少 解题思路:tarjan缩点边树,求出树的直径m,则原有桥数-m即为所求。 本题要注意考虑重边和注意求树的直径的方法(见代码注释) *直径:;任意两个节点之间的最长距离 */ #pragma comment(linker, "/STACK:1024000000,1024000000")///申请空间 #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int maxn=200010; const int maxm=2000014; struct note { int v,next; bool cut,chong_bian; } edge[maxm]; int head[maxn],ip; int n,m; void init() { memset(head,-1,sizeof(head)); ip=0; } void addedge(int u,int v,bool chong_bian) { edge[ip].v=v,edge[ip].cut=false,edge[ip].chong_bian=chong_bian,edge[ip].next=head[u],head[u]=ip++; } int dfn[maxn],low[maxn],dex,inst[maxn],st[maxn],top,cnt,belong[maxn]; void tarjan(int u,int pre,bool ff)///ff代表重边 { dfn[u]=low[u]=++dex; st[top++]=u; inst[u]=1; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(v==pre&&(!ff))continue;///与没有重边的区别 if(!dfn[v]) { tarjan(v,u,edge[i].chong_bian); 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(inst[v]&&dfn[v]<low[u]) { low[u]=dfn[v]; } } if(dfn[u]==low[u]) { cnt++; int v; do { v=st[--top]; inst[v]=0; belong[v]=cnt; } while(v!=u); } } vector <int> vec[maxn]; int dep[maxn]; void dfs(int u)///dfs求每个节点的深度 { for(int i=0; i<vec[u].size(); i++) { int v=vec[u][i]; if(dep[v]!=-1)continue; dep[v]=dep[u]+1; dfs(v); } } void solve() { memset(dfn,0,sizeof(dfn)); memset(inst,0,sizeof(inst)); cnt=dex=top=0; tarjan(1,0,false); for(int i=1;i<=cnt;i++) vec[i].clear(); for(int u=1; u<=n; u++) { for(int i=head[u]; i!=-1; i=edge[i].next) { if(edge[i].cut) { int v=edge[i].v; vec[belong[u]].push_back(belong[v]); } } } ///=======求直径========= memset(dep,-1,sizeof(dep)); dep[1]=0; dfs(1); int k=1; for(int i=1; i<=cnt; i++) { if(dep[i]>dep[k]) k=i; } memset(dep,-1,sizeof(dep)); dep[k]=0; dfs(k); int ans=0; for(int i=1; i<=cnt; i++) { ans=max(ans,dep[i]); } ///======================= printf("%d\n",cnt-1-ans); } struct note_ { int x,y; } node[maxm]; bool cmp(note_ a,note_ b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } int main() { while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; for(int i=0; i<m; i++) { int u,v; scanf("%d%d",&u,&v); if(u==v)continue; if(u>v)swap(u,v); node[i].x=u; node[i].y=v; } sort(node,node+m,cmp); init(); for(int i=0; i<m; i++) { if(i==0||(node[i].x!=node[i-1].x||node[i].y!=node[i-1].y)) { if(i<m-1&&node[i].x==node[i+1].x&&node[i].y==node[i+1].y) { addedge(node[i].x,node[i].y,true); addedge(node[i].y,node[i].x,true); } else { addedge(node[i].x,node[i].y,false); addedge(node[i].y,node[i].x,false); } } } solve(); } return 0; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/44040407