POJ1087-A Plug for UNIX(最大流)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1087-A Plug for UNIX(最大流)相关的知识,希望对你有一定的参考价值。
题意:买了n个插座,m个电器,k个转换器。\\(n(1 <= n <= 100)(1 <= m <= 100)(1 <= k <= 100)\\),转换器会把\\(s1 s2\\)中的s2插座转换成s1插座。
//插座个数
4
A
B
C
D
//插头个数
5
laptop B
phone C
pager B
clock B
comb X
//转换器种类
3
B X
X A
X D
分析:我们可以用map为每个插座赋值一个id,我们从源点向插座连一条容量为1的边,因为每个插座只能适配一个插头。其次,我们为每个插头也赋值一个id,从适配的插座向插头连边,容量为1。然后插头再向汇点连边。我们的交换器比如\\(s1 s2\\),表示s2的插座器可以向s1的插座器连边,容量为inf。因为交换器是无限的。
注意:每次赋值都要判断一个类型的插座或者插头是否存在。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
const int inf = 1 << 29, N = 2005, M = 2 * N;
int h[N], e[M], ne[M], d[N];
int w[M];
int s, t, idx, maxflow;
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
e[idx] = a, w[idx] = 0, ne[idx] = h[b], h[b] = idx++;
}
//构造分层图
bool bfs()
{
memset(d, 0, sizeof d);
queue<int> q;
q.push(s), d[s] = 1;
while (q.size())
{
int u = q.front();
q.pop();
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if (w[i] && !d[j])
{
q.push(j);
d[j] = d[u] + 1;
if (j == t) return true;
}
}
}
return false;
}
int dinic(int u, int flow)
{
if (u == t) return flow;
int rest = flow, k;
for (int i = h[u]; i != -1 && rest; i = ne[i])
{
int j = e[i];
if (w[i] && d[j] == d[u] + 1)
{
k = dinic(j, min(rest, w[i]));
if (!k) d[j] = 0;
w[i] -= k;
w[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
map<string, int> mp;
int main()
{
memset(h, -1, sizeof h);
s = 0, t = 1000;
//插座个数
int n;
scanf("%d", &n);
string name, name2;
int id = 0;
for (int i = 1; i <= n; ++i)
{
cin >> name;
mp[name] = ++id;
//源点向插座连边
add(s, id, 1);
}
int m;
//插头个数
scanf("%d", &m);
for (int i = 1; i <= m; ++i)
{
//插头名和插头类型
cin >> name >> name2;
mp[name] = ++id;
if (mp.find(name2) == mp.end())
{
mp[name2] = ++id;
}
//插座向插头连边
add(mp[name2], mp[name], 1);
//插头向汇点连边
add(mp[name], t, 1);
}
int k;
scanf("%d", &k);
for (int i = 1; i <= k; ++i)
{
cin >> name >> name2;
if (mp.find(name) == mp.end())
mp[name] = ++id;
if (mp.find(name2) == mp.end())
mp[name2] = ++id;
add(mp[name2], mp[name], inf);
}
int flow = 0;
while (bfs())
{
while (flow = dinic(s, inf)) maxflow += flow;
}
printf("%d\\n", m - maxflow);
return 0;
}
以上是关于POJ1087-A Plug for UNIX(最大流)的主要内容,如果未能解决你的问题,请参考以下文章
poj 1087 A Plug for UNIX(字符串编号建图)