bzoj 1191
http://www.lydsy.com/JudgeOnline/problem.php?id=1191
二分+二分图匹配。
首先二分可以答对前mid道题,然后做二分图。
左边是题目,右边是锦囊。
做匈牙利即可。
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<ctime> using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int dblcmp(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} inline void SetOpen(string s) { freopen((s+".in").c_str(),"r",stdin); freopen((s+".out").c_str(),"w",stdout); } inline int Getin_Int() { int res=0,flag=1;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){flag=-flag;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return res*flag; } inline LL Getin_LL() { LL res=0,flag=1;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){flag=-flag;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return res*flag; } const int maxN=1000; const int maxM=1000; int N,M; PII a[maxM+10]; int l,r,mid; int first[maxN+10],now=-1; struct Tedge{int v,next;}edge[2*maxM+100]; inline void addedge(int u,int v) { now++; edge[now].v=v; edge[now].next=first[u]; first[u]=now; } int form[maxM+10]; int vis[maxM+10]; inline int match(int x) { int i,v; for(i=first[x],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v) if(!vis[v]) { vis[v]=1; if(form[v]==-1 || match(form[v])) { form[v]=x; return 1; } } return 0; } inline int check(int mid) { int i; mmst(first,-1);now=-1; re(i,1,mid){addedge(a[i].fi,i);addedge(a[i].se,i);} mmst(form,-1); int tot=0; re(i,1,N) { mmst(vis,0); if(match(i))tot++; } return tot==mid; } int main() { int i; SetOpen("hero"); N=Getin_Int();M=Getin_Int(); re(i,1,M)a[i].fi=Getin_Int()+1,a[i].se=Getin_Int()+1; l=1,r=M; while(l<=r) { int mid=(l+r)/2; if(check(mid))l=mid+1; else r=mid-1; } printf("%d\n",r); /*int tmp=check(r); re(i,1,r)printf("%d\n",form[i]-1);*/ return 0; }