首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

POJ 1087 A Plug for UNIX:最大流建模适配器链

     編輯:關於C++

题目大意

n 个插座,m 个设备,k 种适配器(无限量)。适配器将一种插头转为另一种插座。求最少有多少设备无法插上。

最大流建模

  • 源点 S → 每个插座(容量 1)
  • 每个设备 → 汇点 T(容量 1)
  • 插座类型 → 设备插头类型:若类型匹配,容量 1
  • 适配器 b→a(插座 a,插头 b):类型 b → 类型 a,容量 INF(可级联)
  • 最大流 = 可满足设备数,答案 = m - 最大流

Dinic 算法实现

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int MAXN = 1000, INF = 0x3f3f3f3f;
int mp[MAXN][MAXN], level[MAXN];
map id;
int N, S, T;

bool bfs() {
    memset(level, -1, sizeof(level));
    queue q; q.push(S); level[S] = 0;
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int v=0; v 0 && level[v] == -1) {
                level[v] = level[u] + 1;
                q.push(v);
            }
    }
    return level[T] != -1;
}

int dfs(int u, int f) {
    if (u == T) return f;
    int used = 0;
    for (int v=0; v 0 && level[v] == level[u]+1) {
            int w = dfs(v, min(f-used, mp[u][v]));
            mp[u][v] -= w; mp[v][u] += w;
            used += w;
            if (used == f) return used;
        }
    if (!used) level[u] = -1;
    return used;
}

int dinic() {
    int flow = 0;
    while (bfs()) flow += dfs(S, INF);
    return flow;
}

int main() {
    int n;
    while (scanf("%d", &n) == 1) {
        id.clear(); memset(mp, 0, sizeof(mp));
        int cnt = 1; S = 0; T = 500;
        // 插座
        for (int i=0;i

关键建模细节

  1. 字符串映射:用 map 给每种类型编号
  2. 适配器方向:输入「插座类型 插头类型」→ 边 插头类型 → 插座类型
  3. 无限容量:适配器可级联,用 INF 表示
  4. 多源多汇:超级源连插座,设备连超级汇

复杂度

  • 节点 ≤ 100+100+100×2 ≈ 400
  • Dinic O(E√V) 极快
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved