博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Tarjan,LCA】【3-21个人赛】【problemD】
阅读量:6765 次
发布时间:2019-06-26

本文共 2896 字,大约阅读时间需要 9 分钟。

Problem D

Time Limit : 6000/3000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 249   Accepted Submission(s) : 32

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

WKC有一个收集灯泡的习惯,他把灯泡的阴极都共地,阳极连成一颗树,这样的话,他只要在任意一个灯泡的阳极加上合适的电压,所有灯泡都能亮起来。不幸的是,有一对灯泡之间的阳极连线断掉了,这样的话,这颗灯泡树就还有一部分能亮,一部分不能亮了。WKC想知道如果他在任意一个灯泡的阳极上加电压,这一对灯泡的哪一个会亮?

Input

首先是一个正整数T(1<=T<=10)表示测试数据的组数。
对于每一组测试数据:
第一行是一个整数n,q(3<=n,q<=100000),n表示灯泡总数,q表示查询个数。
接下来的n-1行,每行2个整数x,y(1<=x,y<=n),表示灯泡x和灯泡y的阳极相连。(数据保证合法,是一棵树)
接下来的q行,每行3个整数,a,b,c(1<=a,b,c<=n,数据保证合法,灯泡a和灯泡b之间有边且a不等于b)表示灯泡a和灯泡b之间阳极连线断开的话,在c的阳极加一个电压。

Output

每个查询之间相互独立,对于每个查询输出a和b哪一个会亮,输出a或者b即可。

Sample Input

13 11 22 31 2 3

Sample Output

2

算出 a到c距离,b到c距离 ,算距离用LCA

LCA可以考虑离线的Tarjan算法

Tarjan算法介绍参考这个

http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html

1.注意反向边可以通过 s^1 得到

2.少用#define maxn 1000+5 具体看置顶

代码如下“:

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define oo 0x13131313#define maxn 100010using namespace std;int n,q;struct Edge{int to,ans,next; void GET(int a,int b,int c){to=a,ans=b,next=c;} };struct Node{int first,deep;};Edge E[maxn*6],EE[maxn*6];Node Tree[maxn],Q[maxn];int _E=0,_EE=0;int a[maxn],b[maxn],c[maxn],visit[maxn],father[maxn];void init(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout);}void CLEAR(){ for(int i=1;i<=n;i++) { Tree[i].first=-1; Q[i].first=-1; } memset(visit,0,sizeof(visit)); _E=0;_EE=0; for(int i=1;i<=100001;i++) father[i]=i;}void Link(int u,int v){ E[_E].GET(v,0,Tree[u].first);Tree[u].first=_E++; E[_E].GET(u,0,Tree[v].first);Tree[v].first=_E++;}void Link2(int u,int v){ EE[_EE].GET(v,0,Q[u].first);Q[u].first=_EE++; EE[_EE].GET(u,0,Q[v].first);Q[v].first=_EE++;}int find(int x){ int r=x; while(father[r]!=r) { r=father[r]; } int i=x; while(i!=r) { int j=father[i]; father[i]=r; i=j; } return father[x];}void input(){ int x,y; cin>>n>>q; CLEAR(); for(int i=1;i<=n-1;i++) { scanf("%d%d",&x,&y); Link(x,y); } for(int i=1;i<=q;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); Link2(a[i],c[i]); Link2(b[i],c[i]); }}void Tarjan(int u,int deep){ visit[u]=1; Tree[u].deep=deep; for(int p=Q[u].first;p!=-1;p=EE[p].next) if(visit[EE[p].to]==1) EE[p^1].ans=EE[p].ans=find(EE[p].to); int t=0; for(int p=Tree[u].first;p!=-1;p=E[p].next) { if(visit[E[p].to]==0) { Tarjan(E[p].to,deep+1); father[E[p].to]=u; } }}void solve(){ Tarjan(1,1); int AA=0,BB=0,A=0,B=0;; for(int i=1;i<=q;i++) { for(int p=Q[c[i]].first;p!=-1;p=EE[p].next) { if(EE[p].to==a[i]) A=EE[p].ans; if(EE[p].to==b[i]) B=EE[p].ans; } AA=Tree[a[i]].deep+Tree[c[i]].deep-2*Tree[A].deep; BB=Tree[b[i]].deep+Tree[c[i]].deep-2*Tree[B].deep; if(AA
>T; while(T--) { input(); solve(); }}

转载于:https://www.cnblogs.com/zy691357966/p/5480406.html

你可能感兴趣的文章
HDU 4751 Divide Groups 2013 ACM/ICPC Asia Regional Nanjing Online
查看>>
GROUP BY 與 Null 值
查看>>
01题
查看>>
iOS获取当前设备方向
查看>>
用instsrv.exe将应用程序设置成服务
查看>>
字符型指针变量与字符数组的区别 <转>
查看>>
Collection与Collections的区别
查看>>
cookie 和session的简单比较
查看>>
翻转错误法线
查看>>
SVN cleanup失败的解决方案
查看>>
原生JS实现购物车功能
查看>>
VMware9中安装VMware tools
查看>>
在windows下使用binwalk
查看>>
泪奔,配好了bioconductor环境
查看>>
Oracle双实例切换
查看>>
SQL Server IO 子系统浅究 I
查看>>
HDU-2647-Reward
查看>>
Spring MVC 注解式
查看>>
elasticsearch基本操作之--使用QueryBuilders进行查询
查看>>
HTTP协议
查看>>