洛谷 P2071:座位安排 ← 二分图 + 匈牙利算法 + 二分图最大匹配

​​【题目来源】
https://www.luogu.com.cn/problem/P2071

【题目描述】
已知车上有 N 排座位,有 2N 个人参加省赛,每排座位只能坐两人,且每个人都有自己想坐的排数,问最多使多少人坐到自己想坐的位置。

【输入格式】
第一行,一个正整数 N。
第二行至第 2N+1 行,每行两个正整数 S_{i,1},S_{i,2},为每个人想坐的排数。

【输出格式】
一个非负整数,为最多使得多少人满意。

【输入样例】
4
1 2
1 3
1 2
1 3
1 3
2 4
1 3
2 3

【输出样例】
7

【数据范围】
对于 10% 的数据,n≤10;
对于 30% 的数据,n≤50;
对于 60% 的数据,n≤200;
对于 100% 的数据,n≤2000。

【算法分析】
● 二分图的概念:如果无向图 G=(V, E) 的所有点可以分为两个集合 V1,V2,所有边都在 V1 与 V2 之间,且 V1,V2 的内部都没有边,则称 G 是一个二分图。

● 匈牙利算法:https://blog.csdn.net/hnjzsyjyj/article/details/155256420

● 题设每个人想坐的排数有两个,但每排有两个座位,故每个人有四个座位的选择。若设第 i 个人想坐的排数为 u 及 v,依据上述分析,在二分图中可构建 (i,u)、(i,u+n)、(i,v)、(i,v+n)等四条边。

● 注意代码中 N 及 M 的大小设置。

【算法代码】
本题代码大部分与洛谷 P3386:【模板】二分图最大匹配相同。详见:https://blog.csdn.net/hnjzsyjyj/article/details/155256420

#include <bits/stdc++.h>
using namespace std;

const int N=4e3+5;
const int M=N<<3;
int e[M],ne[M],h[N],idx;
int mate[N],st[N];

void add(int a,int b) {
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

bool HA(int u) { //Hungarian Algorithm
    for(int i=h[u]; i!=-1; i=ne[i]) {
        int j=e[i];
        if(!st[j]) {
            st[j]=true;
            if(!mate[j] || HA(mate[j])) {
                mate[j]=u;
                return true;
            }
        }
    }
    return false;
}

int main() {
    memset(h,-1,sizeof h);
    int n;
    cin>>n;
    for(int i=1; i<=n*2; i++) {
        int u,v;
        cin>>u>>v;
        add(i,u),add(i,u+n);
        add(i,v),add(i,v+n);
    }

    int cnt=0;
    for(int i=1; i<=n*2; i++) {
        memset(st,false,sizeof st);
        if(HA(i)) cnt++;
    }
    cout<<cnt<<endl;

    return 0;
}

/*
in:
4
1 2
1 3
1 2
1 3
1 3
2 4
1 3
2 3

out:
7
*/





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/155345087
https://blog.csdn.net/hnjzsyjyj/article/details/155323274
https://blog.csdn.net/hnjzsyjyj/article/details/155283857
https://blog.csdn.net/hnjzsyjyj/article/details/155256420
https://blog.csdn.net/hnjzsyjyj/article/details/155325141




 

posted @ 2025-11-28 13:11  Triwa  阅读(0)  评论(0)    收藏  举报