首页 > 代码库 > [Sdoi2013]直径(树的直径)
[Sdoi2013]直径(树的直径)
//36分
#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<algorithm>#include<map>using namespace std;typedef long long ll;#define setfire(name) freopen(#name".in","r",stdin);freopen(#name".out","w",stdout);#define fre(name) freopen(#name".txt","r",stdin);#ifdef WIN32#define LL "%lld"#else#define LL "%I64d"#endifconst int N=2e5+5;const int Z=2005;int n,S1,S2,la,lb,s_cnt,b[N],stack[N],prev[N];char s[50];bool vis[N];struct edge{int u,v,next;ll w;}e[N<<1];int tot=1,head[N];int dep[N],fa[N][19];ll ans,LEN,dis[N],dist[N];bool mark[Z][Z];struct data{int x,y;}state[N];inline int read(){ int x=0;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x;}inline void add(int x,int y,int z){ e[++tot].u=x;e[tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot; e[++tot].u=y;e[tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;}void BFS(int S){ int top=1; stack[top]=S;dep[S]=1;fa[S][0]=S; while(top){ int x=stack[top--]; for(int i=head[x];i;i=e[i].next){ if(e[i].v!=fa[x][0]){ fa[e[i].v][0]=x; dep[e[i].v]=dep[x]+1; dist[e[i].v]=dist[x]+e[i].w; stack[++top]=e[i].v; } } }}inline int bfs(int S){ memset(dis,-1,sizeof dis); memset(vis,0,sizeof vis); int id=0,mx=-1,top=1; stack[top]=S;dis[S]=0;vis[S]=1; while(top){ int x=stack[top--]; for(int i=head[x];i;i=e[i].next){ if(!vis[e[i].v]&&dis[e[i].v]<dis[x]+e[i].w){ vis[e[i].v]=1; dis[e[i].v]=dis[x]+e[i].w; if(dis[e[i].v]>mx) mx=dis[e[i].v],id=e[i].v; stack[++top]=e[i].v; } } } return id;}void gosolve(int S,int T){ memset(vis,0,sizeof vis); int id=0,mx=-1,top=1; stack[top]=S;vis[S]=1; while(top){ int x=stack[top--]; for(int i=head[x];i;i=e[i].next){ if(!vis[e[i].v]){ vis[e[i].v]=1; prev[e[i].v]=i; if(e[i].v==T){top=0;break;} stack[++top]=e[i].v; } } } for(int i=T;i!=S;i=e[prev[i]^1].v) b[prev[i]>>1]++;} int lca(int a,int b){ if(dep[a]<dep[b]) swap(a,b); int t=dep[a]-dep[b]; for(int i=0;i<=18;i++){ if(t&(1<<i)){ a=fa[a][i]; } } if(a==b) return a; for(int i=18;i>=0;i--){ if(fa[a][i]!=fa[b][i]){ a=fa[a][i]; b=fa[b][i]; } } return fa[a][0];}void init(){ n=read(); for(int i=1,x,y,z;i<n;i++) x=read(),y=read(),z=read(),add(x,y,z);}void dp_tree_len(int x,int fa){ for(int i=head[x],y;i;i=e[i].next){ if((y=e[i].v)!=fa){ if((x==la&&y==lb)||(x==lb&&y==la)) continue; dp_tree_len(y,x); LEN=max(LEN,dis[x]+dis[y]+e[i].w); dis[x]=max(dis[x],dis[y]+e[i].w); } }}void work(){ if(n<=100){ BFS(1); for(int i=1,mx=0;i<=n;i++) if(dist[i]>mx) mx=dist[i],S1=i; S2=bfs(S1); LEN=dis[S2]; printf("%I64d\n",LEN); for(int j=1;j<=18;j++){ for(int i=1;i<=n;i++){ fa[i][j]=fa[fa[i][j-1]][j-1]; } } ll lt; for(int i=1,anc;i<=n;i++){ for(int j=1;j<i;j++){ if(mark[i][j]) continue; anc=lca(i,j); lt=dist[i]+dist[j]-dist[anc]*2; if(lt==LEN) mark[i][j]=1,state[++s_cnt]=(data){i,j}; } } //直径条数 for(int i=1;i<=s_cnt;i++){ gosolve(state[i].x,state[i].y); } int num=0; for(int i=1;i<=n;i++) if(b[i]==s_cnt) num++; printf("%d",num); } else{ dp_tree_len(1,1); printf("%I64d\n",LEN); }}int main(){ freopen("diameter.in","r",stdin); freopen("diameter.out","w",stdout); int size=64<<20; char *p=(char*)malloc(size)+size; __asm__("movl %0,%%esp\n"::"r"(p)); init(); work(); return 0;}
[Sdoi2013]直径(树的直径)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。