OJ-Problems-Source/HDOJ/5915_dgutfly.cpp

212 lines
5.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
typedef __int64 ll;
const int N=200025;
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int cnt;
int head[N],inu[N],circ[N];
int dep[N][2],pto[N][2],cto[N][2];
int que[N],lop[N];
int to[N<<1],nxt[N<<1];
void addedge(int u,int v)
{
to[cnt]=v;nxt[cnt]=head[u];head[u]=cnt++;
to[cnt]=u;nxt[cnt]=head[v];head[v]=cnt++;
}
//相同路径数的索引号选择
void isvalid(int& a,int& b,int c,int d)
{
int cmpr=min(a,b)-min(c,d);
if(cmpr>0 || (cmpr==0 && max(a,b)>max(c,d)))
a=c,b=d;
}
void bfs(int n)
{
memset(dep,0,sizeof(dep));
memset(circ,0,sizeof(circ));
int tai=0,hed=0,i,u,v;
for(i=0;i<n;i++)
{
if(inu[i]==1)que[tai++]=i;
pto[i][0]=pto[i][1]=cto[i][0]=cto[i][1]=i;//深度为0则端点就是本身
}
while(tai!=hed)
{
u=que[hed++];inu[u]--;
if(circ[u]==dep[u][0]+dep[u][1])
{
isvalid(cto[u][0],cto[u][1],pto[u][0],pto[u][1]);
}
else if(circ[u]<dep[u][0]+dep[u][1])
{
circ[u]=dep[u][0]+dep[u][1];
cto[u][0]=pto[u][0];
cto[u][1]=pto[u][1];
}
for(i=head[u];i!=-1;i=nxt[i])
{
v=to[i];
if(inu[v]<=0)continue;
if(dep[v][0]<dep[u][0]+1)
{
if(dep[v][1]<dep[v][0])
{
dep[v][1]=dep[v][0];
pto[v][1]=pto[v][0];
}
else if(dep[v][1]==dep[v][0] && pto[v][1]>pto[v][0])
{
pto[v][1]=pto[v][0];
}
dep[v][0]=dep[u][0]+1;
pto[v][0]=pto[u][0];
}
else if(dep[v][0]==dep[u][0]+1 && pto[v][0]>pto[u][0])
{
pto[v][0]=pto[u][0];
}
else if(dep[v][1]<dep[u][0]+1)
{
dep[v][1]=dep[u][0]+1;
pto[v][1]=pto[u][0];
}
else if(dep[v][1]==dep[u][0]+1 && pto[v][1]>pto[u][0])
{
pto[v][1]=pto[u][0];
}
if(circ[v]==circ[u])
{
isvalid(cto[v][0],cto[v][1],cto[u][0],cto[u][1]);
}
else if(circ[v]<circ[u])
{
circ[v]=circ[u];
cto[v][0]=cto[u][0];
cto[v][1]=cto[u][1];
}
if(--inu[v]==1)
{
que[tai++]=v;
}
}
}
}
int main()
{
int t,n,u,v,ans,bestu,bestt,i;
scanf("%d",&t);
for(int h=1;h<=t;h++)
{
ans=99999999;bestu=99999999;bestt=99999999;
memset(head,-1,sizeof(head));cnt=0;
memset(inu,0,sizeof(inu));
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&u,&v);u--,v--;
addedge(u,v),inu[u]++,inu[v]++;
}
bfs(n);
int lpl=0,max1=-99999999,pmax1=99999999,max2=-99999999,pmax2=99999999;
for(i=0;inu[i]==0;i++);
for(u=i;inu[u]>=2;u=to[v])
{
lop[lpl++]=u;
for(v=head[u];v!=-1 && inu[to[v]]<2;v=nxt[v]);
if(v==-1)break;
inu[u]--;
}
lop[lpl]=lop[0];
for(i=0;i<lpl;i++)
{
if(circ[lop[i]]==dep[lop[i]][0]+dep[lop[i]][1])
{
isvalid(cto[lop[i]][0],cto[lop[i]][1],pto[lop[i]][0],pto[lop[i]][1]);
}
else if(circ[lop[i]]<dep[lop[i]][0]+dep[lop[i]][1])
{
circ[lop[i]]=dep[lop[i]][0]+dep[lop[i]][1];
cto[lop[i]][0]=pto[lop[i]][0];
cto[lop[i]][1]=pto[lop[i]][1];
}
}
for(i=0;i<lpl;i++)
{
int tmp=2*n-lpl-circ[lop[i]];//s and t are put in the same trees
if(ans==tmp)
{
isvalid(bestu,bestt,cto[lop[i]][0],cto[lop[i]][1]);
}
else if(ans>tmp)
{
ans=tmp;
bestu=cto[lop[i]][0];
bestt=cto[lop[i]][1];
}
//notice:The loop can walk without 1 edge
if(pmax1!=99999999)
{
tmp=2*n-(i+dep[lop[i]][0]+max1)-2;
if(ans==tmp)
{
isvalid(bestu,bestt,pto[lop[i]][0],pto[lop[pmax1]][0]);
}
else if(ans>tmp)
{
ans=tmp;
bestu=pto[lop[i]][0];
bestt=pto[lop[pmax1]][0];
}
}
if(max1<dep[lop[i]][0]-i)
{
max1=dep[lop[i]][0]-i;
pmax1=i;
}
else if(max1==dep[lop[i]][0]-i && pto[lop[pmax1]][0]>pto[lop[i]][0])
{
pmax1=i;
}
if(pmax2!=99999999)
{
tmp=2*n-(lpl-i+dep[lop[lpl-i-1]][0]+max2)-2;
if(ans==tmp)
{
isvalid(bestu,bestt,pto[lop[lpl-i-1]][0],pto[lop[pmax2]][0]);
}
else if(ans>tmp)
{
ans=tmp;
bestu=pto[lop[lpl-i-1]][0];
bestt=pto[lop[pmax2]][0];
}
}
if(max2<dep[lop[lpl-i-1]][0]+i)
{
max2=dep[lop[lpl-i-1]][0]+i;
pmax2=lpl-i-1;
}
else if(max2==dep[lop[lpl-i-1]][0]+i && pto[lop[pmax2]][0]>pto[lop[lpl-i-1]][0])
{
pmax2=lpl-i-1;
}
}
printf("Case #%d: %d %d %d\n",h,ans,min(bestu,bestt)+1,max(bestu,bestt)+1);
}
return 0;
}