分析:
对2_SAT问题还是不熟,比赛的时候感觉像是2_SAT问题,也向这个方向想了,但是没想出来(好菜)。
2_SAT问题核心还是建图:比如这题,怎么建图?对于第
i
层,
然后二分答案,搞定!!!
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef vector <int> VI;
typedef pair <int,int> PII;
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int maxn = 2020;
VI G[maxn];
int dfn[maxn],low[maxn],belong[maxn],mark[maxn],dfs_clock;
stack <int> s;
void dfs(int u){
dfn[u] = low[u] = ++dfs_clock;
s.push(u);
mark[u] = 1;
FOR(i,0,(int)G[u].size()){
int v = G[u][i];
if(!dfn[v]){
dfs(v);
low[u] = min(low[u],low[v]);
}
else if(mark[v]) low[u] = min(low[u],dfn[v]);
}
if(dfn[u] == low[u]){
while(!s.empty()){
int v = s.top(); s.pop();
belong[v] = u;
mark[v] = 0;
if(v == u) break;
}
}
}
int n;
PII point[maxn];
bool solve(){
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(mark,0,sizeof(mark));
dfs_clock = 0;
FOR(i,0,2*n) if(!dfn[i]) dfs(i);
FOR(i,0,2*n) if(belong[i] == belong[2*n-1-i]) return false;
return true;
}
void work(){
int L = 0,R = n;
while(L < R){
int mid = (L+R+1)>>1;
FOR(i,0,n<<1) G[i].clear();
FOR(i,0,mid) G[2*n-1-point[i].fi].pb(point[i].se),
G[2*n-1-point[i].se].pb(point[i].fi);
if(solve()) L = mid;
else R = mid-1;
}
printf("%d\n",L);
}
int main(){
//freopen("test.in","r",stdin);
int T; scanf("%d",&T);
while(T--){
scanf("%d",&n);
FOR(i,0,n) scanf("%d%d",&point[i].fi,&point[i].se);
work();
}
return 0;
}