您的位置:首页 > 其它

Poj 1459 Power Network

2012-01-15 18:49 381 查看
题意:给几个发电站,给几个消耗站,再给几个转发点。发电站只发电,消耗站只消耗电,转发点只是转发电,给出各个传送线的传电能力,求消耗站能获得的最多电是多少。

思路:增加一个超级源点,和超级汇点,转化成最大流问题求解。

#include <cstdio>
#include <memory.h>
#include <iostream>
using namespace std;

const int MAX = 1024;

int n;                // X的大小
int weight [MAX] [MAX];        // X到Y的映射(权重)
int lx [MAX], ly [MAX];        // 标号
bool sx [MAX], sy [MAX];    // 是否被搜索过
int match [MAX];        // Y(i)与X(match [i])匹配

// 初始化权重
void init (int size);
//从X(u)出发寻找增广路径,存在则返回true
bool path (int u);
// 参数maxsum为true,则返回最大权匹配,否则返回最小权匹配
int bestmatch (bool maxsum = true);
int min(int a,int b) {
if ( a<b )
return a;
return b;
}
void init (int size)
{
int i,j;
n = size;
for (i = 0; i < n; i ++)
for (j = 0; j < n; j ++)
scanf ("%d", &weight [i] [j]);
}
bool path (int u)
{
sx [u] = true;
int v;
for (v = 0; v < n; v ++)
if (!sy [v] && lx[u] + ly [v] == weight [u] [v]) {
sy [v] = true;
if (match [v] == -1 || path (match [v])) {
match [v] = u;
return true;
}
}
return false;
}

int bestmatch (bool maxsum)
{
int i, j;
if (!maxsum) {
for (i = 0; i < n; i ++)
for (j = 0; j < n; j ++)
weight [i] [j] = -weight [i] [j];
}

// 初始化标号
for (i = 0; i < n; i ++) {
lx [i] = -0x1FFFFFFF;
ly [i] = 0;
for (j = 0; j < n; j ++)
if (lx [i] < weight [i] [j])
lx [i] = weight [i] [j];
}

memset (match, -1, sizeof (match));
for (int u = 0; u < n; u ++)
while (1) {
memset (sx, 0, sizeof (sx));
memset (sy, 0, sizeof (sy));
if (path (u))
break;

// 修改标号
int dx = 0x7FFFFFFF;
for (i = 0; i < n; i ++)
if (sx [i])
for (j = 0; j < n; j ++)
if(!sy [j])
dx = min (lx[i] + ly [j] - weight [i] [j], dx);
for (i = 0; i < n; i ++) {
if (sx [i])
lx [i] -= dx;
if (sy [i])
ly [i] += dx;
}
}

int sum = 0;
for (i = 0; i < n; i ++)
sum += weight [match [i]] [i];

if (!maxsum) {
sum = -sum;
for (i = 0; i < n; i ++)
for (j = 0; j < n; j ++)
weight [i] [j] = -weight [i] [j];         // 还原weight [ ] [ ]的值
}
return sum;
}
int main()
{
int n,i;
scanf ("%d", &n);
init (n);
int cost = bestmatch (true);

printf ("%d ", cost);
for (i = 0; i < n; i++) {
printf ("Y %d -> X %d ", i, match [i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: