• BZOJ 1305 dance跳舞(最大流+二分答案)


    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1305

    解题思路:
    转自:https://blog.csdn.net/u012288458/article/details/50709571

    二分答案
    每个点拆成两个点x,x'
    每个男生x向x'连一条容量为k的边
    每个女生y'向y连一条容量为k的边
    源点S向每个男生连一条容量为ans的边
    每个女生向汇点T连一条容量为ans的边
    对于男生x和女生y,
    如果互相喜欢,则x向y连一条容量为1的边
    如果不互相喜欢,则x’向y'连一条容量为1的边
    若最大流为n*ans则可行,否则不可行
    点数4n+2
    边数(4n+n^2)*2

    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<vector>
      8 #define LL long long
      9 #define pii pair<int,int>
     10 #define pll pair<long long,long long>
     11 #define rep(i,a,b) for(int i=a;i<=b;i++)
     12 #define per(i,a,b) for(int i=a;i>=b;i--)
     13 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
     14 #define bug cout<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"<<endl;
     15 #define bugc(_) cout << (#_) << " = " << (_) << endl;
     16 using namespace std;
     17 const int N=5e2+5;
     18 const int M=5e3+5;
     19 const int INF=0x3f3f3f3f;
     20 
     21 struct node{
     22     int to,next,flow;
     23 }edge[M*2];
     24 
     25 int cnt,st,en,n,k;
     26 int head[N],dep[N],like[N][N];
     27 
     28 void init(){
     29     cnt=2;
     30     memset(head,0,sizeof(head));
     31 }
     32 
     33 void link(int u,int v,int flow){
     34     edge[cnt]=node{v,head[u],flow};
     35     head[u]=cnt++;
     36     edge[cnt]=node{u,head[v],0};
     37     head[v]=cnt++;
     38 }
     39 
     40 int bfs(){
     41     memset(dep,0,sizeof(dep));
     42     dep[st]=1;
     43     queue<int>q;
     44     q.push(st);
     45     while(!q.empty()){
     46         int u=q.front();
     47         q.pop();
     48         for(int i=head[u];i;i=edge[i].next){
     49             node t=edge[i];
     50             if(t.flow&&!dep[t.to]){
     51                 dep[t.to]=dep[u]+1;
     52                 q.push(t.to);
     53             }
     54         }
     55     }
     56     return dep[en];
     57 }
     58 
     59 int dfs(int u,int fl){
     60     if(u==en) return fl;
     61     for(int i=head[u];i;i=edge[i].next){
     62         node &t=edge[i];
     63         if(t.flow&&dep[u]+1==dep[t.to]){
     64             int x=dfs(t.to,min(t.flow,fl));
     65             if(x>0){
     66                 t.flow-=x;    
     67                 edge[i^1].flow+=x;
     68                 return x;
     69             }
     70         }
     71     }
     72     dep[u]=-2;
     73     return 0;
     74 }
     75 
     76 int dinic(){
     77     int ans=0;
     78     while(bfs()){
     79         while(int d=dfs(st,INF)){
     80             ans+=d;
     81         }
     82     }
     83     return ans;
     84 }
     85 
     86 void build(int mid){
     87     init(); 
     88     for(int i=1;i<=n;i++){
     89         link(st,i,mid);
     90         link(i,i+n,k);
     91         link(i+2*n,en,mid);
     92         link(i+3*n,i+2*n,k);
     93     }
     94     for(int i=1;i<=n;i++){
     95         for(int j=1;j<=n;j++){
     96             if(like[i][j])
     97                 link(i,j+2*n,1);
     98             else
     99                 link(i+n,j+3*n,1);
    100         }
    101     }
    102 }
    103 
    104 int main(){
    105     while(~scanf("%d%d",&n,&k)){
    106         for(int i=1;i<=n;i++){
    107             char tmp[100];
    108             scanf("%s",tmp+1);
    109             for(int j=1;j<=n;j++){
    110                 if(tmp[j]=='Y')
    111                     like[i][j]=1;
    112             }
    113         }
    114         st=0,en=4*n+1;
    115         int l=0,r=n,ans=-1;
    116         while(l<=r){
    117             int mid=(l+r)/2;
    118             build(mid);
    119             int sum=dinic();
    120             if(sum>=n*mid){
    121                 ans=mid;
    122                 l=mid+1;
    123             }
    124             else
    125                 r=mid-1;
    126         }
    127         printf("%d
    ",ans);
    128     }
    129     return 0;
    130 }
  • 相关阅读:
    sqlhelper中事务的简单用法(初学者)
    sqlhelper中事务的简单用法(初学者)
    sqlhelper中事务的简单用法(初学者)
    【】SQlServer数据库生成简单的说明文档小工具(附源码)
    【】SQlServer数据库生成简单的说明文档小工具(附源码)
    一种M2M业务的架构及实现M2M业务的方法
    【】SQlServer数据库生成简单的说明文档小工具(附源码)
    程序员搜索技巧
    通用的Sql存储过程
    python安装过程的一些问题解决方案
  • 原文地址:https://www.cnblogs.com/fu3638/p/9880040.html
Copyright © 2020-2023  润新知