• 【BZOJ 1305】[CQOI2009]dance跳舞


    【链接】 我是链接,点我呀:)
    【题意】

    在这里输入题意

    【题解】

    男生和女生每个人都分身成两个节点 即x[1],x[2]和y[1],y[2]

    然后如果i和j不相互喜欢
    那么add(x[i][2],y[j][2],1)
    如果相互喜欢的话
    add(x[i][1],y[j][1],1)

    然后对于每个男生
    add(x[i][1],y[i][1],k)

    对于每个女生
    add(y[i][2],y[i][1],k)

    然后对于每个男生
    add(s,x[i][1],mid)
    add(y[i][1],t,mid)

    这里的mid是二分的值。

    这个mid就是舞会的轮数了。

    如果能够满流显然每个人都能配对跳mid支舞
    显然是有单调性的。
    (然后发现原来的dicnic的模板是错的。。边数的计算要特别careful.

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 50;
    
    struct abc{
        int nex,en,flow;
    }bian[2][N*N*2+8*N+10];
    
    int n,k,x[N+10][3],y[N+10][3],fir[2][N*4+10],tfir[N*4+10],totm,deep[N*4+10];
    int cnt = 0;
    bool bo[N+10][N+10];
    char s[N+10];
    queue<int> dl;
    
    //每个男人分为(x1,x2)
    //每个女人分为(y1,y2)
    
    void add(int x,int y,int cost,int i){
        bian[i][totm].nex = fir[i][x];
        fir[i][x] = totm;
        bian[i][totm].en = y,bian[i][totm].flow = cost;
        totm++;
    
        bian[i][totm].nex = fir[i][y];
        fir[i][y] = totm;
        bian[i][totm].en = x,bian[i][totm].flow = 0;
        totm++;
    }
    
    bool bfs(int s,int t){
        dl.push(s);
        memset(deep,255,sizeof deep);
        deep[s] = 0;
    
        while (!dl.empty()){
            int x = dl.front();
            dl.pop();
            for (int temp = fir[1][x]; temp!= -1 ;temp = bian[1][temp].nex){
                int y = bian[1][temp].en;
                if (deep[y]==-1 && bian[1][temp].flow>0){
                    deep[y] = deep[x] + 1;
                    dl.push(y);
                }
            }
        }
        return deep[t]!=-1;
    }
    
    int dfs(int x,int t,int limit){
        if (x == t) return limit;
        if (limit == 0) return 0;
        int cur,f = 0;
        for (int temp = tfir[x];temp!=-1;temp = bian[1][temp].nex){
            tfir[x] = temp;
            int y = bian[1][temp].en;
            if (deep[y] == deep[x] + 1 && (cur = dfs(y,t,min(limit,bian[1][temp].flow))) ){
                f += cur;
                limit -= cur;
                bian[1][temp].flow -= cur;
                bian[1][temp^1].flow += cur;
                if (!limit) break;
            }
        }
        return f;
    }
    
    int get_flow(){
        int now = 0;
        while (bfs(0,cnt)){
            for (int i = 0;i <= cnt;i++) tfir[i] = fir[1][i];
            int xxx = dfs(0,cnt,10000);
            now+=xxx;
        }
        return now;
    }
    
    int main(){
        //freopen("F:\program\rush\rush_in.txt","r",stdin);
        ios::sync_with_stdio(0),cin.tie(0);
        memset(fir[0],255,sizeof fir[0]);
        cin >> n >> k;
        for (int i = 1;i <= n;i++){
            cin >> (s+1);
            for (int j = 1;j <= n;j++)
                if (s[j]=='Y'){
                    bo[i][j] = 1;
                }
        }
        for (int i = 1;i <= n;i++){
            for (int j = 1;j <= 2;j++)
                x[i][j] = ++cnt;
        }
    
        for (int i = 1;i <= n;i++)
            for (int j = 1;j <= 2;j++)
                y[i][j] = ++cnt;
    
        cnt++;
        for (int i = 1;i <= n;i++){
            for (int j = 1;j <= n;j++){
                if (bo[i][j])
                    add(x[i][1],y[j][1],1,0);
                else{
                    add(x[i][2],y[j][2],1,0);
                }
            }
        }
    
        for (int i = 1;i <= n;i++){
            add(x[i][1],x[i][2],k,0);
            add(y[i][2],y[i][1],k,0);
        }
    
        int l = 0,r = n+1,temp1 = 0;
        while (l<=r){
            int i = (l+r)>>1;
    
            for (int j = 0;j < totm;j++) bian[1][j] = bian[0][j];
            for (int j = 0;j <= cnt;j++) fir[1][j] = fir[0][j];
            int tt = totm;
    
            for (int j = 1;j <= n;j++){
                add(0,x[j][1],i,1);
                add(y[j][1],cnt,i,1);
            }
            int temp = get_flow();
    
            if (temp!=i*n){
                r = i-1;
            }else {
                temp1 = i;
                l = i+1;
            }
            totm = tt;
        }
        cout<<temp1<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    BZOJ4383 : [POI2015]Pustynia
    BZOJ4382 : [POI2015]Podział naszyjnika
    BZOJ4381 : [POI2015]Odwiedziny
    BZOJ4380 : [POI2015]Myjnie
    BZOJ4378 : [POI2015]Logistyka
    BZOJ3424 : Poi2013 Multidrink
    BZOJ4367 : [IOI2014]holiday假期
    BZOJ4369 : [IOI2015]teams分组
    BZOJ4421 : [Cerc2015] Digit Division
    BZOJ1315 : Ural1557Network Attack
  • 原文地址:https://www.cnblogs.com/AWCXV/p/9088540.html
Copyright © 2020-2023  润新知