您的位置:首页 > 理论基础 > 计算机网络

NOIP2016#模拟考试 Day.2# T2 网络修复 【LCA + 并查集】

2016-07-23 08:13 519 查看
LCA + 并查集

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int N,T;
#define maxn 200000
struct edge{
int v;
edge* next;
}e[maxn<<1];
edge* head[maxn];
int a[maxn],b[maxn];
int totedge = 0;
void adde(int u,int v)
{
edge* p = e+(++totedge);
p->v=v;
p->next=head[u];
head[u]=p;
}
#define mod  998244353
int R = 0;
int K = 0;
int dep[maxn];
int p[maxn][25];

void dfs(int u,int fa)
{
dep[u]=dep[fa]+1;
for(int i=1;i<=20;i++)p[u][i]=p[p[u][i-1]][i-1];
for(edge* i = head[u];i;i=i->next)
{
int v = i->v;
if(v!=fa)
{
p[v][0]=fa;
dfs(v,u);
}
}
}
int lca(int a,int b)
{
if(dep[a]>dep[b])swap(a,b);
for(int i=20;i>=0;i--)if(dep[a]+ (1<<i) <= dep[b])a = p[a][i];
if(a==b)return a;
for(int i=20;i>=0;i--)
{
if(p[a][i]==p[b][i])continue;
a=p[a][i];
b=p[b][i];
}
return p[a][0];
}
//union-set
int fa[maxn];

int find(int u)
{
if(fa[u]==u)return u;
else return fa[u]=find(fa[u]);
}
int main()
{
#define LOC
#ifdef LOC
freopen("network.in","r",stdin);
freopen("network.out","w",stdout);
#endif
scanf("%d%d",&N,&T);
for(int i=1;i<N;i++)
{
scanf("%d%d",&a[i],&b[i]);
adde(a[i],b[i]);
adde(b[i],a[i]);
}
dfs(1,0);
for(int i=1;i<=N;i++)fa[i]=i;
char c;
int e;
for(int i=1;i<=T;i++)
{
scanf("%s",&c);
if(c=='Q')
{
int u,v;
scanf("%d%d",&u,&v);

int fu = find(u);
int fv = find(v);

if(fu!=fv)
{
R = R ^ (i + u + v);
}

else
{
K = dep[u]+dep[v]-dep[lca(u,v)]*2;
R = (R + (i ^ K)) %  998244353;
}
}
else
{
scanf("%d",&e);
int fx = find(a[e]);
int fy = find(b[e]);
fa[fx]=fy;
}
}
printf("%d",R);
return 0;
}
/*
1. 某一条网络线路恢复通畅;
2. Gemini 想知道某两台计算机之间是否已经连通,如果连通,从一台计算机到另一台计
算机要经过多少条网络线路。
为了避免大量输出,你需要按照如下方式处理你的输出。
声明一个 32 位有符号整型变量 R,赋值为 0。将所有事件按照发生顺序(即输入文件中给出
的顺序)编号为 1 ~ T。按以下指示遍历所有操作。
如果第 i 个事件为“C e”,则不对 R 做任何处理。
如果第 i 个事件为“Q a b”,且 a,b 不连通,则 R = R ^ (i + a + b)。
如果第 i 个事件为“Q a b”,且 a,b 连通,且从计算机 a 到计算机 b 要经过 K 条网络线路,
则 R = (R + (i ^ K)) % 998244353。
最终输出 R 的值。
(^代表二进制下的异或操作,%代表取模操作。)
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCA 并查集