1. 程式人生 > >牛客多校----E Room

牛客多校----E Room

room
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
題目描述
Nowcoder University has 4n students and n dormitories ( Four students per dormitory). Students numbered from 1 to 4n.

And in the first year, the i-th dormitory ‘s students are (x1[i],x2[i],x3[i],x4[i]), now in the second year, Students need to decide who to live with.

In the second year, you get n tables such as (y1,y2,y3,y4) denote these four students want to live together.

Now you need to decide which dormitory everyone lives in to minimize the number of students who change dormitory.

輸入描述:
The first line has one integer n.

Then there are n lines, each line has four integers (x1,x2,x3,x4) denote these four students live together in the first year

Then there are n lines, each line has four integers (y1,y2,y3,y4) denote these four students want to live together in the second year
輸出描述:
Output the least number of students need to change dormitory.
示例1
輸入
複製
2
1 2 3 4
5 6 7 8
4 6 7 8
1 2 3 5
輸出
複製
2
說明
Just swap 4 and 5
備註:
1<=n<=100

1<=x1,x2,x3,x4,y1,y2,y3,y4<=4n

It’s guaranteed that no student will live in more than one dormitories.

假設新的宿舍裡,第 i 個4人團體安排到第 j 間宿舍,那麼不用搬的學生數量,
就是4人團體和原住民的交,那麼費用就是用搬的學生數量,
變成帶權二分圖匹配問題,可以用費用流做(直接構完圖用最小費用最大流模板求解)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int MAXN = 1010;
const int MAXM = 40010;

typedef struct Node{
    int s,to,next,capacity,value;
}Node;

int n,m;
int ecnt;
Node node[MAXM];
int pre[MAXN];
int head[MAXN];
int dis[MAXN];
bool vis[MAXN];

void init()
{
    ecnt = 0;
    memset(head,-1,sizeof(head));
    memset(node,0,sizeof(node));
}

void addEdge(int u,int v,int w,int c)
{
    node[ecnt].to = v;
    node[ecnt].s = u;
    node[ecnt].capacity = c;//流量
    node[ecnt].value = w;//路徑長度是費用
    node[ecnt].next = head[u];
    head[u] = ecnt++;
    node[ecnt].to = u;
    node[ecnt].s = v;
    node[ecnt].capacity = 0;//流量
    node[ecnt].value = -w;//路徑長度是費用
    node[ecnt].next = head[v];
    head[v] = ecnt++;
}

bool spfa(int s,int t,int nnum)
{
    memset(vis,0,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    for(int i = 0;i <= nnum;++i)
    {
        dis[i] = inf;
    }
    queue<int>que;
    que.push(s);
    dis[s] = 0;
    vis[s] = true;
    while(!que.empty())
    {
        int temp = que.front();
        que.pop();
        vis[temp] = false;
        for(int i = head[temp];i + 1;i = node[i].next)
        {
            if(node[i].capacity)
            {
                int ne = node[i].to;
                if(dis[temp] + node[i].value < dis[ne]){
                    dis[ne] = dis[temp] + node[i].value;
                    pre[ne] = i;
                    if(!vis[ne]){
                        que.push(ne);
                        vis[ne] = true;
                    }
                }
            }
        }
    }
    if(dis[t] == inf)
        return false;
    return true;
}

int getMincost(int s,int t,int nnum)
{
    int ans_flow = 0;
    int ans_cost = 0;
    int temp,minc;
    while(spfa(s,t,nnum))
    {
//        cout << 0 << endl;
        temp = t;
        minc = inf;
        while(pre[temp] != -1)
        {
            minc = min(node[pre[temp]].capacity,minc);
            temp = node[pre[temp]].s;
        }
        temp = t;
        while(pre[temp] != -1)
        {
            node[pre[temp]].capacity -= minc;
            int ss = pre[temp] ^ 1;
            node[ss].capacity += minc;
            temp = node[pre[temp]].s;
        }
        ans_cost += dis[t] * minc;
    }
    return ans_cost;
}

typedef struct room{
    int num[4];
}room;
room a[MAXN],b[MAXN];

int main()
{
    while(~scanf("%d",&n))
    {
        init();
        for(int i = 0;i < n;++i)
        {
            for(int j = 0;j < 4;++j)
            {
                scanf("%d",&a[i].num[j]);
            }
        }
        for(int i = 0;i < n;++i)
        {
            for(int j = 0;j < 4;++j)
            {
                scanf("%d",&b[i].num[j]);
            }
        }
        for(int i = 0;i < n;++i)
        {
            for(int j = 0;j < n;++j)
            {
                int v = 0;
                for(int k = 0; k < 4;++k)
                {
                    for(int p = 0;p < 4;++p)
                    {
                        if(a[i].num[k] == b[j].num[p])
                            v++;
                    }
                }
                //第 i 個4人團體安排到第 j 間宿舍,需要搬的學生數量
                //只能搬一次,所以邊的容量為1
                addEdge(i + 1,n + j + 1,4 - v,1);
            }
        }
        //新增源點和匯點
        //與源點和匯點連線的邊費用為0
        for(int i = 0;i < n;++i)
        {
            addEdge(0,i + 1,0,1);
            addEdge(n + i + 1,2 * n + 1,0,1);
        }
        int ans;
        printf("%d\n",getMincost(0,2 * n + 1,2 * n + 1));
    }
    return 0;
}

相關推薦

----E Room

room 時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld 題目描述 Nowcoder University has 4n students and

Room

i++ ger nes class cout wan bits its truct 鏈接:https://www.nowcoder.com/acm/contest/143/E來源:牛客網 時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他

2018第九場E(動態規劃,思維,取模)

pac namespace for ons mod 思維 space scan 動態規劃 #include<bits/stdc++.h>using namespace std;const long long mod=1000000007,inv=57000000

第三場 E Sort String(字串hash)

題目描述 Eddy likes to play with string which is a sequence of characters. One day, Eddy has played with a string S for a long time and won

Different Integers 第一場只會簽到題

sts memset nbsp tdi num contains 簡單 輸出 struct Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..

第一場 F Sum of Maximum

i+1 -- main freopen pre map contest d+ 拉格朗日 題目鏈接 https://www.nowcoder.com/acm/contest/139/F 分析 枚舉i從1到a[i]的最大值,每個段考慮i的貢獻。 關鍵在於要在O(n)或者O(nl

2 D-money(dp記錄/貪心)

-i dpf item data price 64bit class print https D-money 鏈接:https://www.nowcoder.com/acm/contest/140/D來源:牛客網 時間限制:C/C++ 1秒,其他語言2秒 空間限制

3 C-Shuffle Cards(rope大法解決數組分塊)

always href dict sil however cli ++ gic -s Shuffle Cards 鏈接:https://www.nowcoder.com/acm/contest/141/C來源:牛客網 時間限制:C/C++ 1秒,其他語言2秒 空間

Different Integers(第一場+莫隊做法)

tdi har lock def ack type void *** 種類 題目鏈接:https://www.nowcoder.com/acm/contest/139/J 題目: 題意:給你n個數,q次查詢,對於每次查詢得l,r,求1~l和r~n元素得種類。

第四場 G Maximum Mode

clas pear contain 記錄 The 但是 -m out appear 鏈接:https://www.nowcoder.com/acm/contest/142/G來源:牛客網 The mode of an integer sequence is the valu

2018 2

我們 $1 做了 撤銷 最小值 神奇 problem 數組 前綴 Problem A Problem B 考慮第二種優惠,每一個物品如果原價購買了, 那麽向可以免費拿的那個物品連一條邊(在樹上被指向的那個點是父親) 如果不考慮環的話,考慮樹上DP。 設$f[

第五場-D-inv

item return text 因此 .... src acm ... ati 鏈接:https://www.nowcoder.com/acm/contest/143/D來源:牛客網 題目描述 Kanade has an even number n and a

2018第五場 H.subseq

print int space 跳出循環 date open 遞增 code play 題意:   給出a數組的排列。求出字典序第k小的b數組的排列,滿足1<=bi<=n,bi<bi+1,a[b[i]]<a[b[i+1]],m>0。 題解:  

20186 - I Team Rocket KD樹維護空間

再次 double sync main get set print esp operator 題意:給出n條鐵路區間\([L,R]\),共有m個boom依時間順序放置在\(k_i\)中,區間與\(k_i\)有交集的都被炸掉 求每次炸掉的鐵路個數和最後輸出所有id被炸的時間點

<round 6>

walk close span ase pri bsp its std round Solved:3 rank:156 J. Heritage of skywalker 學習一下nth_element 可以o (n)的找出前多少大的元素 #include <b

7

ase ace rst gcc 技術分享 prot 好的 bre size A 隊友寫的。 //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack

第六場C

++ 預處理 ima class -s inf using com false 一個數很大,並不能預處理,所以要進行公式變換,存前一個的值就好 #include <bits/stdc++.h> using namespace std; typede

2018第九場暑期 F --- KMP

題意:        給定n(<4)個字串,然後有一個操作:逐個輸入一個長為L字串,字串中出現 減號 代表刪除一個字元,問每次輸入一個字元或者刪除一個字元後再輸入最少多少個 字尾能出現前面n個字串之一. 分析:    

第五場 F - take (樹狀陣列)

題目連結 初始的時候手裡有大小為0的鑽石,現在依次開啟n個箱子,第i個箱子有x/100的概率開出大小為y的鑽石。如果開出的鑽石比手中的要大,就交換一次。求交換次數的期望。 考慮要在某個位置交換,就必須滿足在它前面的比它大的鑽石都沒有被開出來。 也就是,第i個位置對答案的貢獻是。 對於

(割圓問題與費馬小定理)8 G題

連結:https://www.nowcoder.com/acm/contest/146/G 來源:牛客網   時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 131072K,其他語言262144K 64bit IO Format: %lld 題目描述 Niuni