HDU3277MarriageMatchIII
来源:互联网 发布:淘宝足球正品店铺 编辑:程序博客网 时间:2024/05/19 02:42
HDU3277MarriageMatchIII
题意:和上一篇差不多,就是多了每个女孩可以另外选任意k个不喜欢的;
#include <cstdio>#include <cstdlib>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#define LL long long#define Inf 0x7fffffffusing namespace std;int fa[500];int dis[1010],cur[1010],gap[1010],head[1010],x[62510],y[62510],pre[1010];int g[255][255];int len,n,m,k,f,st,ed;struct node{ int v,next,w;}t[5000010];void add(int x,int y,int w){ t[len].next=head[x]; t[len].v=y; t[len].w=w; head[x]=len++;}int Isap(){ int flow=0,d=Inf,i,flag=0,u; for (i=0; i<=ed; i++) { dis[i]=gap[i]=0; cur[i]=head[i]; } gap[0]=ed+1; u=pre[st]=st; while (dis[st]<ed+1) { flag=false; //printf("%d %d\n",u,dis[u]); for (int &j=cur[u]; j!=-1; j=t[j].next) { int v=t[j].v; if (t[j].w>0 && dis[v]+1==dis[u]) {//printf("dfa"); d=min(d,t[j].w); flag=true; pre[v]=u; u=v; //printf("%d ==",u); if (u==ed) { flow+=d; while (u!=st) { u=pre[u]; t[cur[u]].w-=d; t[cur[u]^1].w+=d; } d=Inf; } break; } } if (flag) continue ; int minh=ed+1; for (int j=head[u]; j!=-1; j=t[j].next)//wrong { int v=t[j].v; if (t[j].w>0 && minh>dis[v])//wrong { minh=dis[v]; cur[u]=j; } } --gap[dis[u]]; if (gap[dis[u]]==0) break; dis[u]=minh+1; gap[dis[u]]++; u=pre[u]; } return flow;}bool check(int p){ int i,j; if (p==0) return true; memset(head,-1,sizeof(head)); len=0; for (i=1; i<=n; i++) { add(st,i,p); add(i,st,0); add(i,i+n,k); add(i+n,i,0); add(2*n+i,ed,p); add(ed,2*n+i,0); } for (i=1; i<=n; i++) { for (j=1; j<=n; j++) if (g[i][j]) { add(i,2*n+j,1); add(2*n+j,i,0); } else { add(n+i,2*n+j,1); add(2*n+j,n+i,0); } } int ans=Isap(); if (ans==n*p) return true; else return false;}void getans(){ int l=0,r=n; int i,j; st=0,ed=3*n+1; while (r-l>=2) { int mid=(l+r)/2; if (check(mid)) l=mid; else r=mid; } for (i=r; i>=l; i--) if (check(i)) { printf("%d\n",i); break; }}int find(int x){ if (fa[x]==x) return x; else return fa[x]=find(fa[x]);}void join(int a,int b){ int x=find(a),y=find(b); if (x==y) return ; if (x<y) fa[y]=x; else fa[x]=y;}int main(){ int i,j,T; int a,b; freopen("1.in","r",stdin); scanf("%d",&T); while (T--) { memset(g,0,sizeof(g)); scanf("%d%d%d%d",&n,&m,&k,&f); for (i=1; i<=n; i++) fa[i]=i; for (i=1; i<=m; i++) { scanf("%d%d",&x[i],&y[i]);//wrong yue jie } for (i=1; i<=f; i++) { scanf("%d%d",&a,&b); join(a,b); } for (i=1; i<=m; i++) g[find(x[i])][y[i]]=1; for (i=1; i<=n; i++) for (j=1; j<=n; j++) if (g[find(i)][j]) g[i][j]=1; getans(); } return 0;}
0 0