标签:强制 bsp char s 题目 加密 信息 cst std 网格
题目描述
比特哈顿镇有n*n个格点,形成了一个网格图。一开始整张图是完整的。
有k次操作,每次会删掉图中的一条边(u,v),你需要回答在删除这条边之后u和v是否仍然连通。
输入
第一行包含两个正整数n,k(2<=n<=1500,1<=k<=2n(n-1)),表示网格图的大小以及操作的个数。
接下来k行,每行包含两条信息,每条信息包含两个正整数a,b(1<=a,b<=n)以及一个字符c(c=N或者E)。
如果c=N,表示删除(a,b)到(a,b+1)这条边;如果c=E,表示删除(a,b)到(a+1,b)这条边。
数据进行了加密,对于每个操作,如果上一个询问回答为TAK或者这是第一个操作,那么只考虑第一条信息,否则只考虑第二条信息。
数据保证每条边最多被删除一次。
输出
输出k行,对于每个询问,如果仍然连通,输出TAK,否则输出NIE。
样例输入
3 4
2 1 E 1 2 N
2 1 N 1 1 N
3 1 N 2 1 N
2 2 N 1 1 N
样例输出
TAK
TAK
NIE
NIE
题解
对偶图+并查集
由于强制在线,不能时光倒流+加边。
考虑对偶图。
对于每条线段挨着的两个面积块,如果它们之间是连通的,
则删除这条线段后这两个面积块会在一个环中,且这个环包含且只包含两个端点中的一个(即一个点在环里,一个点在环外),不能连通。
反过来也成立。
所以只需要把平面图删边转化为对偶图加边就可以了。
然后用并查集维护一下连通性即可。
#include <cstdio>
int f[2250010] , id[1510][1510];
char str[5];
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
int n , k , i , j , a , b , x , y , tx , ty , last = 0;
scanf("%d%d" , &n , &k);
n -- ;
for(i = 1 ; i <= n ; i ++ )
id[0][i] = id[i][n + 1] = id[i][0] = id[n + 1][i] = 0;
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
id[i][j] = (i - 1) * n + j;
for(i = 0 ; i <= n * n ; i ++ )
f[i] = i;
while(k -- )
{
if(last) scanf("%*d%*d%*s%d%d%s" , &a , &b , str);
else scanf("%d%d%s%*d%*d%*s" , &a , &b , str);
if(str[0] == ‘N‘) x = id[a - 1][b];
else x = id[a][b - 1];
y = id[a][b];
tx = find(x) , ty = find(y);
if(tx != ty) puts("TAK") , last = 0;
else puts("NIE") , last = 1;
f[tx] = ty;
}
return 0;
}
【bzoj4423】[AMPPZ2013]Bytehattan 对偶图+并查集
标签:强制 bsp char s 题目 加密 信息 cst std 网格
原文地址:http://www.cnblogs.com/GXZlegend/p/6527190.html