UVa1459/LA4748 Flowers Placement

UVa1459/LA4748 Flowers Placement

题目链接

  本题是2009年icpc亚洲区域赛上海赛区的题目

题意

  花卉展上有一种m行n列(m≤n)的矩形的摆放n种花的方式,每一行的n格中放的花互不相同,每一列的m格中放的花也互不相同。现在想再按此规则追加摆放一行花,输出字典序第k个合理摆放方案,第k个方案不存在时输出-1。1≤N≤200,0≤M≤N,1≤K≤200。

分析

  二分图+dfs枚举剪枝,思路来自这篇博客

  找出每列可以放的花的编号,连边,接着跑一下二分图匹配,看能否完美匹配,如果不能的话,表示无法摆放。跑这个二分图匹配不是白跑的,后面用得上。
  因为要第k个字典序,所以要枚举每一列所能摆放的花。这里需要一个剪枝,如果当前枚举的列为第j列,往后的j+1到第N列如果无法进行匹配的话,那么就可以剪掉了。

AC 代码

#include <iostream>
#include <cstring>
using namespace std;

#define N 205
int g[N][N], f[N][N], c[N], px[N], py[N], vis[N], ans[N], p1[N], p2[N], m, n, k, clk; bool use[N];

bool dfs(int u, int pos = -1) {
    if (u <= pos) return false;
    vis[u] = clk;
    for (int i=0, v; i<c[u]; ++i) if (py[v = g[u][i]] < 0 || (vis[py[v]]!=clk && dfs(py[v], pos))) {
        px[u] = v; py[v] = u;
        return true;
    }
    return false;
}

int max_match() {
    memset(px, -1, sizeof(px)); memset(py, -1, sizeof(py)); memset(vis, -1, sizeof(vis));
    int cc = 0;
    for (int i=1; i<=n; ++i) if (px[i] < 0 && dfs(clk = i)) ++cc;
    return cc;
}

bool ok(int u, int v) {
    if (px[u] == v) return true;
    int x = 0;
    for (int i=1; i<=n; ++i) {
        p1[i] = px[i]; p2[i] = py[i];
        if (px[i] == v) if ((x = i) < u) return false;
    }
    px[x] = py[px[u]] = -1; px[u] = v; py[v] = u; ++clk;
    if (dfs(x, u)) return true;
    for (int i=1; i<=n; ++i) px[i] = p1[i], py[i] = p2[i];
    return false;
}

bool find(int u) {
    if (u > n) return ++m == k;
    for (int i=0, v; i<c[u]; ++i) if (!use[v = g[u][i]] && ok(u, v)) {
        use[v] = true; ans[u] = v;
        if (find(u+1)) return true;
        use[v] = false;
    }
    return false;
}

void solve () {
    cin >> n >> m >> k;
    for (int i=1; i<=m; ++i) for (int j=1; j<=n; ++j) cin >> f[i][j];
    for (int i=1; i<=n; ++i) {
        memset(vis, c[i] = 0, sizeof(vis));
        for (int j=1; j<=m; ++j) vis[f[j][i]] = true;
        for (int j=1; j<=n; ++j) if (!vis[j]) g[i][c[i]++] = j;
    }
    if (max_match() != n) {
        cout << " -1" << endl;
        return;
    }
    memset(use, m = 0, sizeof(use)); memset(vis, clk = 0, sizeof(vis));
    if (find(1)) {
        for (int i=1; i<=n; ++i) cout << ' ' << ans[i];
        cout << endl;
    } else cout << " -1" << endl;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int t; cin >> t;
    for (int k=1; k<=t; ++k) cout << "Case #" << k << ':', solve();
    return 0;
}

相关推荐

  1. UVa1459/LA4748 Flowers Placement

    2024-07-12 06:44:05       25 阅读
  2. UVA1449 Dominating Patterns 题解

    2024-07-12 06:44:05       52 阅读
  3. UVa1116/LA2429 Puzzle

    2024-07-12 06:44:05       27 阅读
  4. UVa1516/LA5906 Smoking gun

    2024-07-12 06:44:05       31 阅读
  5. UVA-213

    2024-07-12 06:44:05       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 06:44:05       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 06:44:05       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 06:44:05       62 阅读
  4. Python语言-面向对象

    2024-07-12 06:44:05       72 阅读

热门阅读

  1. MybatisPlus 一些技巧

    2024-07-12 06:44:05       26 阅读
  2. 云计算练习题

    2024-07-12 06:44:05       27 阅读
  3. 怎么在ad原理图中替换器件

    2024-07-12 06:44:05       24 阅读
  4. 目标识别步骤

    2024-07-12 06:44:05       26 阅读
  5. vs QT Use QGuiApplication::screens报错

    2024-07-12 06:44:05       27 阅读
  6. 【qml学习笔记】QML与C++的交互

    2024-07-12 06:44:05       30 阅读
  7. stm32使用串口打印

    2024-07-12 06:44:05       23 阅读
  8. Windows驱动开发

    2024-07-12 06:44:05       29 阅读
  9. [linux] git push时需要输入user 和keyword

    2024-07-12 06:44:05       24 阅读
  10. 【AIGC】GPT-4深度解析:自然语言处理的新纪元

    2024-07-12 06:44:05       23 阅读
  11. PyTorch中的CPU和GPU代码实现详解

    2024-07-12 06:44:05       27 阅读