一直不知道BZOJ的XXXX题为什么错了……
日哦……那题调了一周了……然后现在对拍都没找到错……
然后自我感觉不能颓!于是水了一道并查集题……
4423: [AMPPZ2013]Bytehattan
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 146 Solved: 104
[ Submit][ Status][ Discuss]
Description
比特哈顿镇有n*n个格点,形成了一个网格图。一开始整张图是完整的。
有k次操作,每次会删掉图中的一条边(u,v),你需要回答在删除这条边之后u和v是否仍然连通。
Input
第一行包含两个正整数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或者这是第一个操作,那么只考虑第一条信息,否则只考虑第二条信息。
数据保证每条边最多被删除一次。
Output
输出k行,对于每个询问,如果仍然连通,输出TAK,否则输出NIE。
Sample Input
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
2 1 E 1 2 N
2 1 N 1 1 N
3 1 N 2 1 N
2 2 N 1 1 N
Sample Output
TAK
TAK
NIE
NIE
TAK
NIE
NIE
HINT
Source
一句话题解……先把平面图转化成对偶图,如果删去的这一边是桥也就是NIE的话,很显然桥两边相连通,然后并查集一下就水过了TAT
#include "stdio.h"
#include "iostream"
#define EMPTY n*n-2*n+2
#define rep(f,a,b) for(f=a;f<=b;f++)
using namespace std;
const int N=1505;
int read(){
int v=0; char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch<='9'&&ch>='0') { v=v*10+ch-'0'; ch=getchar();}
return v;
}
int fa[N*N],n,m,last;
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
inline int c(int x,int y){
if(x&&y&&x<n&&y<n) return (x-1)*(n-1)+y;
return EMPTY;
}
int main(){
n=read(); m=read(); int i,j; fa[EMPTY]=EMPTY;
rep(i,1,n-1) rep(j,1,n-1) fa[c(i,j)]=c(i,j);
int xi,yi,vk,a,b; char ci,ck;
rep(i,1,m) {
xi=read(),yi=read(); ci=getchar();
if(last){ xi=read(),yi=read(); ci=getchar();}
else {vk=read(),vk=read(); ck=getchar();}
if(ci=='E') a=c(xi,yi),b=c(xi,yi-1);
else a=c(xi,yi),b=c(xi-1,yi);
if(find(a)^find(b)) fa[fa[a]]=fa[b],last=0;
else last=1;
if(last) puts("NIE");
else puts("TAK");
}
return 0;
}