tarjan
树的直径
HDU4612
给定一个无向连通图,求增加一条边后,割边的最少可能的条数
先用 t a r j a n tarjan tarjan缩点(边双连通分量),剩下的就是割边构成的树,我们在任意两点间加边,就等于在他们所在的边双连通分量加边
于是两个点在树上的链加上加的边构成的一个环,就减少了链长的割边
想要割边最少就是求树的直径
树的直径可以用新建图加两遍 d f s dfs dfs
所以: t a r j a n tarjan tarjan缩点+树的直径
注:手动开栈
数据大,深搜会爆栈
int size = 8 << 20; //256兆,size代表栈空间的字节数
char *p = (char*)malloc(size) + size;//开栈空间,esp为栈顶指针,因而要加size
__asm__("movl %0, %%esp\n" :: "r"(p));//内嵌汇编
记下来吧,紧接 m a i n main main函数
#pragma comment(linker, "/STACK:10240000000000,10240000000000")
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+4,M=1e6+4;
struct edge{
int u,v,nxt;
}e[M<<1],r[M<<1];
int first[N],cnt=1,cn=0,ct=0;
int n,m,tot=0,idx=0,dfn[N],low[N],vis[N],q[N],top=0,scc[N];
bool cut[M<<1];
inline void add(int u,int v){
e[++cnt].v=v;e[cnt].u=u;
e[cnt].nxt=first[u];first[u]=cnt;
}
inline void add2(int u,int v){
r[++ct].v=v;r[ct].nxt=first[u];first[u]=ct;
}
inline void tarjan(int x,int from){
q[++top]=x;vis[x]=1;
dfn[x]=low[x]=++idx;
for(int i=first[x],v;i;i=e[i].nxt){
v=e[i].v;
if(!dfn[v]){
tarjan(v,i);
low[x]=min(low[x],low[v]);
if(low[v]>dfn[x]){
cut[i]=cut[i^1]=1;
tot++;
}
}
if((i^1)!=from)low[x]=min(low[x],dfn[v]);
}
if(low[x]==dfn[x]){
++cn;
while(1){
int w=q[top--];
vis[w]=0;scc[w]=cn;
if(w==x)break;
}
}
}
int ans=0,mx=0;
inline void dfs(int x,int dep,int fa){
if(dep>mx){mx=dep;ans=x;}
for(int i=first[x],v;i;i=r[i].nxt){
v=r[i].v;
if(v==fa)continue;
dfs(v,dep+1,x);
}
}
int main(){
int size = 8 << 20; //256兆,size代表栈空间的字节数
char *p = (char*)malloc(size) + size;//开栈空间,esp为栈顶指针,因而要加size
__asm__("movl %0, %%esp\n" :: "r"(p));//内嵌汇编
while(1){
scanf("%d%d",&n,&m);
if(!n&&!m)return 0;
memset(first,0,sizeof(first));
cnt=1;ans=mx=cn=ct=top=tot=idx=0;
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
memset(cut,0,sizeof(cut));
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i,0);
memset(first,0,sizeof(first));
for(int i=2;i<=cnt;i+=2)
if(cut[i]){
add2(scc[e[i].u],scc[e[i].v]);
add2(scc[e[i].v],scc[e[i].u]);
}
dfs(1,0,0);
mx=0;
dfs(ans,0,0);
printf("%d\n",tot-mx);
}
return 0;
}