完结撒花!!!!!!!!!!!

最后一题填坑1A仙人掌WWWWWWW我真流弊

首先把环拆开,环中每一个点连向环的根,然后搞LCA,答案就是套路的d[x]+d[y]-d[lca]*2

然后就可以发现,其实只有当fx和fy在同一个环里面,才有可能通过不同的路线导致答案更小,特判之即可。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std; struct node
{
int x,y,d,next;
}a[],e[];int len,last[],elen,elast[];
void ins(int x,int y,int d)
{
len++;
a[len].x=x;a[len].y=y;a[len].d=d;
a[len].next=last[x];last[x]=len;
}
void eins(int x,int y,int d)
{
elen++;
e[elen].x=x;e[elen].y=y;e[elen].d=d;
e[elen].next=elast[x];elast[x]=elen;
} bool edg[];int cnt,bel[],sum[],ts[];
int fa[],dep[],dis[];
int tp,id[],sdis[];
void DP(int rt,int bac)
{
tp=dep[bac]-dep[rt]+;
for(int i=;i<=tp;i++) id[tp-i+]=bac, bac=fa[bac]; sdis[]=;
for(int i=;i<=tp;i++)
{
sdis[i]=sdis[i-]+dis[id[i]];
ts[id[i]]=sdis[i];
}
cnt++;sum[cnt]=sdis[tp]+dis[rt]; for(int i=;i<=tp;i++)
{
ins(rt,id[i],min(sdis[i],sum[cnt]-sdis[i]));
edg[id[i]]=true;
bel[id[i]]=cnt;
}
}
int z,dfn[],low[];
void cactus(int x)
{
dfn[x]=low[x]=++z;
for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(dfn[y]==)
{
fa[y]=x;
dep[y]=dep[x]+;
dis[y]=e[k].d;
cactus(y);
low[x]=min(low[x],low[y]);
}
else if(y!=fa[x])
low[x]=min(low[x],dfn[y]);
} for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(fa[y]!=x&&dfn[x]<dfn[y])
{
int t=dis[x];
dis[x]=e[k].d;
DP(x,y);
dis[x]=t;
}
}
} //----------------------------------------- int Bin[];
int f[][];
void dfs(int x)
{
for(int i=;dep[x]>=Bin[i];i++)f[i][x]=f[i-][f[i-][x]]; for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=f[][x])
{
f[][y]=x;
dep[y]=dep[x]+;
dis[y]=dis[x]+a[k].d;
dfs(y);
}
}
}
int LCA(int x,int y,int &fx,int &fy)
{
int w=-;
if(dep[x]<dep[y]){swap(x,y);w=;}
for(int i=;i>=;i--)
if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
if(x==y){fx=-;return x;}
for(int i=;i>=;i--)
if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
if(w==-)fx=x,fy=y;
else fx=y,fy=x;
return f[][x];
} //--------------get_LCA---------------------------- int main()
{
int n,m,Q,x,y,dd;
scanf("%d%d%d",&n,&m,&Q);
len=;memset(last,,sizeof(last));
elen=;memset(elast,,sizeof(elast));
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&dd);
eins(x,y,dd);eins(y,x,dd);
}
z=cnt=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(edg,false,sizeof(edg));
fa[]=,dep[]=,cactus();
for(int i=;i<=n;i++)
if(edg[i]==false)
ins(fa[i],i,dis[i]); Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
f[][]=;dep[]=;dis[]=;dfs(); while(Q--)
{
scanf("%d%d",&x,&y);
int fx,fy,lca=LCA(x,y,fx,fy);
if(fx!=-&&bel[fx]!=&&bel[fx]==bel[fy])
{
dd=abs(ts[fx]-ts[fy]);
printf("%d\n",dis[x]-dis[fx]+dis[y]-dis[fy]+min(dd,sum[bel[fx]]-dd));
}
else
printf("%d\n",dis[x]+dis[y]-*dis[lca]);
}
return ;
}

最新文章

  1. git 版本回退
  2. CDH离线数据导入solr:利用MapReduceIndexerTool将json文件批量导入到solr
  3. 【转】Checkpoint--与lazy writer区别
  4. Homebrew安装及使用
  5. kickstart note
  6. 自定义NSLog宏输出
  7. 在国内时,更新ADT时需要配置的
  8. WCF之各种WCF引用方式
  9. 8款必备的免费移动Web开发框架(HTML5/JS)
  10. [RxJS] AsyncSubject
  11. 逐行返回http响应的内容
  12. Eclipse选中变量名,相同变量都变色显示 的设置
  13. crawler_Docker_解决用 JavaScript 框架开发的 Web 站点抓取
  14. HDU 2177 取(2堆)石子游戏 (威佐夫博弈)
  15. hack:选择符前缀法,样式属性前缀法
  16. js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( ))
  17. (双指针) leetcode 27. Remove Element
  18. Win10使用VNC连接Centos7远程桌面
  19. Linux修改hostname与免密码登录
  20. redis 配置文件解释 以及集群部署

热门文章

  1. JS高级——浏览器的线程
  2. Python语言之变量1(数值,字符串,布尔)
  3. Ajax无刷新显示
  4. cesium的学习
  5. php银联支付
  6. iview中Modal弹窗做form表单验证相关问题
  7. Django - 一对多创建
  8. strcpy &amp; memcpy区别
  9. 57 和为S的数字
  10. Entertainment Box Gym100781E(数据结构+贪心)