Time Limit: 1000MS
Memory Limit: 65536KB
2 3 0 0 1 1 2 2 3 0 0 1 1 5 5
3 2 蒟蒻没听过2-sat dfs bfs xjb搜各种超时爆内存 今天学了下2-sat 这题主要技巧在 二分枚举可能通过的关 ACcode:#include <map> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <stdlib.h> #include <iostream> #include <algorithm> #define maxn 10000 using namespace std; struct Node{int to,next;}edge[maxn]; int head[maxn],tot; void add(int u,int v){edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;} int low[maxn],dfn[maxn],Stack[maxn],Belong[maxn]; bool Instack[maxn]; int Index,scc,top; void init(){tot=0;memset(head,-1,sizeof(head));} void tarjan(int u){ int v; low[u]=dfn[u]=++Index; Stack[top++]=u; Instack[u]=true; for(int i=head[u];i!=-1;i=edge[i].next){ v=edge[i].to; if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);} else if(Instack[v]&&low[u]>dfn[v])low[u]=dfn[v]; } if(low[u]==dfn[u]){ scc++; do{ v=Stack[--top]; Instack[v]=false; Belong[v]=scc; }while(v!=u); } } void solve(int n){ memset(dfn,0,sizeof(dfn)); memset(Instack,false,sizeof(Instack)); Index=scc=top=0; for(int i=0;i<n;++i)if(!dfn[i])tarjan(i); } int x[maxn],y[maxn]; int main(){ int t,n,a,b,N; scanf("%d",&t); while(t--){ scanf("%d",&n);N=2*n-1; for(int i=0;i<n;++i) scanf("%d%d",&x[i],&y[i]); int lf=0,rt=n; while(lf<=rt){ init(); int mid=(lf+rt)>>1; for(int i=0;i<mid;++i){ add(N-x[i],y[i]); add(N-y[i],x[i]); } solve(2*n); bool flag=true; for(int i=0;i<n&&flag;++i) if(Belong[i]==Belong[N-i]) flag=false; if(flag)lf=mid+1; else rt=mid-1; } printf("%d\n",(lf+rt)/2); } return 0; }