pku 1087 A Plug for UNIX 网络流 解题报告
十分郁闷的一题,与其说是练习算法与编程,还不如说练习你的英语.算法一般般,很多人都能想到.不是最大流就是利用二分图.可我在这过程中,总是建错图.原因在于没有理解好题意啊.像sample:
4
A
B
C
D
5
laptop B
phone C
pager B
clock B
comb X
3
B X
X A
X D
n=4,其中A、B、C、D指的是插座而且是可以直接通电的,而m=5下,左边的是电器,右边的则是电器相对应的插座,同时不一定是直接通电的,像X就是这样.但剩下的k=3,则是插座两两之间的联系.像B与X联系,X与A联系,X与D联系,那么laptop则可以直接与B连接通电,或者通过X与A、D连接通电.其他的以此类推.
AC代码:(采用最大流的算法)
#include <stdio.h>
#include <string.h>
#define inf 21100000
#define MAXN 505
int n, m, k, total, source, sink;
int mat[MAXN][MAXN], flow[MAXN][MAXN];
char device[MAXN][30];
int get_id(char b[])
{
int i;
for (i = 1; i <= total; i++)
{
if (strcmp(device[i], b) == 0)
{
return i + m - 1;
}
}
total++;
strcpy(device[i], b);
return i + m - 1;
}
void init()
{
int i, ii, j, jj;
char a[MAXN][30], b[30], c[30];
source = 0; total = 1;
memset(mat, 0, sizeof(mat));
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%s", a[i]);
}
scanf("%d", &m);
for (i = 1; i <= m; i++)
{
mat[0][i] = 1;
scanf("%s %s", b, c);
j = get_id(c);
mat[i][j] = 1;
}
scanf("%d", &k);
for (i = 1; i <= k; i++)
{
scanf("%s %s", b, c);
j = get_id(b);
jj = get_id(c);
mat[j][jj] = inf;
}
for (i = 1; i <= n; i++)
{
j = get_id(a[i]);
}
ii = m + total;
for (i = 1; i <= n; i++)
{
j = get_id(a[i]);
mat[j][ii] = 1;
}
sink = ii;
n = ii + 1;
}
//返回最大流量,flow返回每条边的流量
//传入网络节点数n,容量mat,源点source,汇点sink
int max_flow()
{
int pre[MAXN], que[MAXN], d[MAXN], p, q, t, i, j;
if (source == sink)
{
return inf;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
flow[i][j] = 0;
}
}
while (1)
{
for (i = 0; i < n; i++)
{
pre[i] = 0;
}
t = source;
pre[t] = 1;
d[t] = inf;
for (p = q = 0; p <= q && !pre[sink]; )
{
for (i = 0; i < n; i++)
{
if (!pre[i] && (j = mat[t][i] - flow[t][i]))
{
pre[que[q++] = i] = t + 1;
d[i] = d[t] < j ? d[t] : j;
}
else if (!pre[i] && (j = flow[i][t]))
{
pre[que[q++] = i] = - t - 1;
d[i] = d[t] < j ? d[t] : j;
}
}
t = que[p++];
}
if (!pre[sink])
{
break;
}
for (i = sink; i != source;)
{
if (pre[i] > 0)
{
flow[pre[i] - 1][i] += d[sink];
i = pre[i] - 1;
}
else
{
flow[i][-pre[i] - 1] -= d[sink];
i = -pre[i] - 1;
}
}
}
for (j = i = 0; i < n; j += flow[source][i++])
{
;
}
return j;
}
int main()
{
init();
int ans, temp = max_flow();
if (temp > m)
{
ans = m;
}
else
{
ans = m - temp;
}
printf("%d/n", ans);
return 0;
}