题解:
2-sat
二分最后的答案,然后2-sat判断是否可行
代码:
#include<cstring> #include<cstdio> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> using namespace std; const int N=10000; struct rec{int x,y;}p[N],q[N]; int n,m,sum,tot,dfn[N],low[N],belong[N],instack[N]; vector<int> e[N]; stack<int> s; void tarjan(int u) { int i; dfn[u]=low[u]=++tot; s.push(u); instack[u]=1; int size=e[u].size(); for (i=0;i<size;i++) { int v=e[u][i]; if (!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if (instack[v]) low[u]=min(low[u],dfn[v]); } if (dfn[u]==low[u]) { sum++; do { i=s.top(); s.pop(); instack[i]=0; belong[i]=sum; }while (i!=u); } } int pd(int d) { for (int i=0;i<4*n;i++) e[i].clear(); for (int i=0;i<n;i++) { e[q[i].x*2].push_back(q[i].y*2+1); e[q[i].y*2].push_back(q[i].x*2+1); } for (int i=0;i<d;i++) { e[p[i].x*2+1].push_back(p[i].y*2); e[p[i].y*2+1].push_back(p[i].x*2); } memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(instack,0,sizeof(instack)); memset(belong,0,sizeof(belong)); sum=tot=0; for (int i=0;i<4*n;i++) if (!dfn[i]) tarjan(i); for (int i=0;i<2*n;i+=2) if (belong[i]==belong[i+1]) return 0; return 1; } int solve() { int l=0,r=m; while (l<r) { int mid=(l+r); if (pd(mid))l=mid; else r=mid-1; } return l; } int main() { while (~scanf("%d%d",&n,&m),n||m) { for (int i=0;i<n;i++)scanf("%d%d",&q[i].x,&q[i].y); for (int i=0;i<m;i++)scanf("%d%d",&p[i].x,&p[i].y); printf("%d ",solve()); } return 0; }