Topic: given n boys and n girls, some like each other and some not. Hold a few dances, each with n pairs. Cannot have the same combination to appear. Each person can only dance with the people they don't like, ask for a few dances.
Split a person into two points. Point 1 to point 2 is connected to an edge with a flow of K. Two people if they like each other, point 1 between the edge, do not like the point 2 between the edge
For each x value to be validated, each person's point 1 to the source or sink a flow to the edge of X
Then the two-point answer runs the maximum flow can be
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 220# Define INF 0x3f3f3f3f#define S 0#define T (n<<2|1) using namespace std;struct abcd{int to,f,next;} Table[100100];int head[m],tot=1;int N,k;char s[m];int dpt[m];bool BFS () {static int q[m],r,h;int i;memset (dpt,-1,sizeof DPT); R=h=0;q[++r]=s;dpt[s]=1;while (r!=h) {int x=q[++h];for (i=head[x];i;i=table[i].next) if (table[i].f&&!~ Dpt[table[i].to]) {dpt[table[i].to]=dpt[x]+1;q[++r]=table[i].to;if (table[i].to==t) return true;}} return false;} int dinic (int x,int flow) {int i,left=flow;if (x==t) return flow;for (I=head[x];i&&left;i=table[i].next) if ( table[i].f&&dpt[table[i].to]==dpt[x]+1) {int temp=dinic (table[i].to, Min (left,table[i].f)); if (!temp) dpt[ Table[i].to]=-1;left-=temp;table[i].f-=temp;table[i^1].f+=temp;} return flow-left;} inline void Add (int x,int y,int z) {Table[++tot].to=y;table[tot].f=z;table[tot].next=head[x];head[x]=tot;} inline void Link (int x,int y,int z) {AdD (x, y, z); ADD (y,x,0);} inline void Restore () {int i;for (i=2;i<=tot;i+=2) table[i].f+=table[i^1].f,table[i^1].f=0;} BOOL Judge (int x) {int i; Restore (); for (i=tot-(n<<2) +1;i<=tot;i+=2) table[i].f=x;int Ans=0;while (BFS ()) ans+=dinic (S,inf); return Ans==n*x;} int bisection () {int L=0,r=n;while (l+1<r) {int mid=l+r>>1;if (Judge (mid)) L=mid;elser=mid;} if (Judge (r)) return R;return l;} int main () {int i,j;cin>>n>>k;for (i=1;i<=n;i++) {Link (i,n+i,k); Link (n+n+i,n+n+n+i,k);} for (i=1;i<=n;i++) {scanf ("%s", s+1), and for (j=1;j<=n;j++) {if (s[j]== ' Y ') Link (i,n+n+n+j,1); Elselink (n+i,n+n+j,1) ;}} for (i=1;i<=n;i++) {Link (s,i,0); Link (n+n+n+i,t,0);} Cout<<bisection () <<endl;} 0 Source Point//1~n Male first point//n+1~2n male second point//2n+1~3n female second point//3n+1~4n female first point//4n+1 meeting point
Bzoj 1305 CQOI2009 Dance Dancing two-point answer + Max stream