Description
Input
Output
Sample Input
3 6 0 3 1 2 4 5 0 1 0 2 4 1 4 2 3 5 2 2 0 0
Sample Output
4
Source
#include<queue> #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N =(1<<10); struct node { int from; int to; int next; }edge[N*N],redge[N*N]; int head[4*N],rhead[N]; bool instack[4*N]; int DFN[4*N],block[4*N],color[4*N],in_deg[4*N],low[4*N],Stack[4*N],cfl[4*N]; int index,tot,sccnum,Top,rtot,n,m; struct pp { int u,v; }que1[N*2],que2[N*2]; void addedge(int from,int to) { edge[tot].from=from; edge[tot].to=to; edge[tot].next=head[from]; head[from]=tot++; } /*void raddedge(int from,int to) { redge[rtot].from=from; redge[rtot].to=to; redge[rtot].next=rhead[from]; rhead[from]=rtot++; }*/ void tarjan(int u) { DFN[u]=low[u]=++index; instack[u]=1; Stack[Top++]=u; for (int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if (DFN[v]==-1) { tarjan(v); if(low[u]>low[v]) low[u]=low[v]; } else if (instack[v] && low[u]>DFN[v]) low[u]=DFN[v]; } if (DFN[u]==low[u]) { int v; sccnum++; do { Top--; v=Stack[Top]; block[v]=sccnum; instack[v]=0; } while (v!=u); } } /*void topo_sort() { queue<int>qu; memset(color,0,sizeof(color)); for (int i=1;i<=sccnum;i++) if (in_deg[i]==0) qu.push(i); while (!qu.empty()) { int u=qu.front(); qu.pop(); if (!color[u]) { color[u]=1; color[cfl[u]]=-1; } for (int i=rhead[u];i!=-1;i=redge[i].next) { int v=redge[i].to; in_deg[v]--; if (!in_deg[v]) qu.push(v); } } }*/ bool judge() { for (int i=0;i<2*n;i++) { if (block[2*i]==block[2*i+1]) return false; //cfl[block[2*i]]=block[2*i+1]; //cfl[block[2*i+1]]=block[2*i]; } return true; } void init() { memset(block,-1,sizeof(block)); memset(DFN,-1,sizeof(DFN)); memset(instack,0,sizeof(instack)); index=sccnum=Top=0; } /*void r_build() { memset(in_deg,0,sizeof(in_deg)); memset(rhead,-1,sizeof(rhead)); rtot=0; for (int i=0;i<tot;i++) { int u=edge[i].from; int v=edge[i].to; if (block[u]!=block[v]) { raddedge(block[v],block[u]); in_deg[block[u]]++; } } }*/ /*void solve() { build(); init(); for (int i=1;i<=2*n;i++) if (DFN[i]==-1) tarjan(i); if (!judge()) printf("bad luck\n"); else { bool flag=false; r_build(); topo_sort(); }*/ int main() { while (~scanf("%d%d",&n,&m)) { if(n==0 && m==0) break; int l=0,r=m,mid; int a,b; for(int i=0;i<n;i++) { scanf("%d%d",&a,&b);//N对钥匙,每对钥匙只能取1个 que1[i].u=a; que1[i].v=b; } for(int i=0;i<m;i++) scanf("%d%d",&que2[i].u,&que2[i].v); int ans=0; int u,v; while(l<=r) { init(); memset(head,-1,sizeof(head)); tot=0; mid=(l+r)>>1; for(int i=0;i<n;i++) { u=que1[i].u; v=que1[i].v; addedge(2*u,2*v+1); addedge(2*v,2*u+1); } for(int i=0;i<mid;i++) { u=que2[i].u; v=que2[i].v; addedge(2*u+1,2*v); addedge(2*v+1,2*u); } for(int i=0;i<4*n;i++) if(DFN[i]==-1) tarjan(i); if(!judge()) r=mid-1; else { ans=mid; l=mid+1; } } printf("%d\n",ans); } return 0; }