zoukankan      html  css  js  c++  java
  • Gym

    题意:有N个宿舍(N<200),给出第一年每个宿舍有哪4个同学。现在给出N个4元组y[][4],表示这4个人想住一起,问最少多少人需要换宿舍。

    思路:费用流,每个4元组y[]到每个宿舍连边,流量是1,费用是4-same。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    const int inf=1<<30;
    const int maxn=1000010;
    using namespace std;
    int To[maxn*6],Laxt[maxn],Next[maxn*6],cap[maxn*6],cost[maxn*6];
    int S,T,cnt=1,dis[maxn],ans;
    bool inq[maxn],vis[maxn];
    deque<int>q;
    void add(int u,int v,int c,int cc)
    {
        Next[++cnt]=Laxt[u];Laxt[u]=cnt;
        To[cnt]=v;cap[cnt]=c;cost[cnt]=cc;
    }
    bool spfa()
    {
        for(int i=0;i<=T;i++) inq[i]=0;
        for(int i=0;i<=T;i++) dis[i]=inf;
        inq[T]=1; dis[T]=0; q.push_back(T);
        while(!q.empty())
        {
            int u=q.front(); q.pop_front();
            inq[u]=0;
            for(int i=Laxt[u];i;i=Next[i])
            {
                int v=To[i];
                if(cap[i^1]&&dis[v]>dis[u]-cost[i])
                {
                    dis[v]=dis[u]-cost[i];
                    if(!inq[u]){
                        inq[v]=1;
                        if(q.empty()||dis[v]>dis[q.front()]) q.push_back(v);
                        else q.push_front(v);
                    }
                }
            }
        }
        return dis[S]<inf;
    }
    int dfs(int u,int flow)
    {
        vis[u]=1;
        if(u==T||flow==0) return flow;
        int tmp,delta=0;
        for(int i=Laxt[u];i;i=Next[i])
        {
            int v=To[i];
            if((!vis[v])&&cap[i]&&dis[v]==dis[u]-cost[i])
            {
                tmp=dfs(v,min(cap[i],flow-delta));
                delta+=tmp; cap[i]-=tmp; cap[i^1]+=tmp;
            }
        }
        return delta;
    }
    int x[maxn][4],y[maxn][4];
    int main()
    {
        int N;
        scanf("%d",&N);
        rep(i,1,N) rep(j,0,3) scanf("%d",&x[i][j]);
        rep(i,1,N) rep(j,0,3) scanf("%d",&y[i][j]);
        rep(i,1,N) sort(x[i],x[i]+4);
        rep(i,1,N) sort(y[i],y[i]+4);
        S=0,T=N+N+1; cnt=1;
        rep(i,1,N) add(S,i,1,0),add(i,S,0,0);
        rep(i,1,N) add(N+i,T,1,0),add(T,N+i,0,0);
        rep(i,1,N) rep(j,1,N) {
            int L1=0,L2=0,same=0;
            while(L1<=3&&L2<=3) {
                if(x[i][L1]==y[j][L2]) same++,L1++,L2++;
                else if(x[i][L1]<y[j][L2]) L1++;
                else L2++;
            }
            add(i,N+j,1,4-same); add(N+j,i,0,same-4);
        }
        int ans=0;
        while(spfa()){
            vis[T]=1;
            while(vis[T]){
                for(int i=0;i<=T;i++) vis[i]=0;
                ans+=dis[S]*dfs(S,inf);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    《iBoard 是什么》之简介
    [iBoard 电子学堂][第八卷 设计任意波发生器]第一篇 iBoard 任意波发生器简介
    [iBoard 电子学堂][第〇卷 电子基础]第二篇 电路图与印刷电路板
    职业规划提示
    督查督办工作基本程序
    今天收拾了个电脑抽屉,发现原来我是个有钱人
    VB之SendKeys键盘模拟
    天骄辅助外挂制作,寻求合作
    用CE找武林外传一级基址的方法
    asp实现数据记录的备份及恢复抛砖引玉
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11460113.html
Copyright © 2011-2022 走看看