您的位置:首页 > 其它

【hackerrank】World CodeSprint 11 T4

2017-06-03 22:11 387 查看

题目大意

给出一个n个点有向图及q个操作

1:给出x、d,加入第n+1个点,并与x相连,d=0表示从x练到n+1,d=1表示从n+1练到x;

2:给出x、y,询问从x出发能否到y;

解题思路

在原图上Tarjan缩环,它就变成了一个DAG,用bitset维护点与点之间的连通性;

然后之后连接上去的点不会再构成新的环,所以询问就变成了树上的问题。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#define maxn 50006
#define fr(i,a,b) for(i=a;i<=b;i++)
using namespace std;
using std::bitset;
typedef long long ll;

bitset<maxn> bits[maxn];
struct poi
{
int x;
poi *nex;
} *a[maxn],*b[maxn];

int i,n,m,q,x,y,z,tot,top,col,sum[maxn],dep[maxn],bel[maxn];
int dfn[maxn],low[maxn],sta[maxn],c[maxn],f[maxn],ind[maxn];
bool kan[maxn];
void link(int x,int y)
{
poi *p=new poi;
p->x=y;
p->nex=a[x];
a[x]=p;
return;
}
void linkk(int x,int y)
{
poi *p=new poi;
p->x=y;
p->nex=b[x];
b[x]=p;
return;
}
void tarjan(int x)
{
poi *p=new poi;
dfn[x]=low[x]=++tot;
sta[++top]=x,kan[x]=1;
for(p=a[x];p;p=p->nex)
if (!dfn[p->x])
{
tarjan(p->x);
low[x]=min(low[x],low[p->x]);
} else if (kan[p->x])
low[x]=min(low[x],dfn[p->x]);
if (dfn[x]==low[x])
{
++col;
while (sta[top]!=x)
{
c[sta[top]]=col;
kan[sta[top--]]=0;
}
c[x]=col,kan[x]=0,--top;
}
return;
}
void ahah()
{
poi *p=new poi;
int i,j=0,u;
fr(i,1,n)
{
bits[i][i]=1;
if (!ind[i]) f[++j]=i,kan[i]=1;
}
i=0;
while (i<j)
{
u=f[++i];
for(p=b[u];p;p=p->nex)
{
bits[p->x]|=bits[u];
if (!kan[p->x])
f[++j]=p->x,kan[p->x]=1;
}
}
return;
}
int main()
{
freopen("fou.in","r",stdin);
scanf("%d%d",&n,&m);
fr(i,1,m)
{
scanf("%d%d",&x,&y);
link(x,y);
}
fr(i,1,n)
if (!dfn[i]) tarjan(i);
poi *p=new poi;
fr(i,1,n)
for(p=a[i];p;p=p->nex)
linkk(c[p->x],c[i]),++ind[c[i]];
memset(kan,0,sizeof(kan));
ahah();
scanf("%d",&q);
fr(i,1,n) bel[i]=c[i];
fr(i,1,q)
{
scanf("%d%d%d",&z,&x,&y);
if (z==1)
{
bel[++n]=bel[x];
sum
=sum[x]+y;
dep
=dep[x]+1;
} else
{
if (c[x] && c[y])
printf(bits[c[x]].test(c[y])?"Yes\n":"No\n");
else if (!c[x] && c[y])
{
if (sum[x]==dep[x] && bits[bel[x]].test(c[y]))
printf("Yes\n");
else printf("No\n");
} else if (c[x] && !c[y])
{
if (sum[y]==0 && bits[c[x]].test(bel[y]))
printf("Yes\n");
else printf("No\n");
} else if (!c[x] && !c[y])
{
if (bel[x]==bel[y])
{
if (dep[x]>dep[y] && (sum[x]-sum[y])==(dep[x]-dep[y]))
printf("Yes\n");
else if (dep[y]>dep[x] && (sum[y]-sum[x])==0)
printf("Yes\n");
else printf("No\n");
} else
{
if (sum[x]==dep[x] && bits[bel[x]].test(bel[y]) && sum[y]==0)
printf("Yes\n");
else printf("No\n");
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bitset