http://acm.pku.edu.cn/JudgeOnline/problem?id=3436

题目大意:每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在。且每个机器的加工都有一个performance,要求能得到的最大performance.

算法分析:最大流,没用到一点优化,依然不会sap,dinic,直接bfs()搞定的,不过这次的bfs(),我没有用STL,而是手动模拟了一下,又学习到一个好的模拟队列方法,不用更新队列,直接更新长度,将值都放在同一个数组里存着,按顺序出队就行了。继续努力!

总结一点:做图论题,关键就在建图,找到建图方法,只要有模板,并且熟悉,就能很快解决了。做题时,不要过早放弃,多想想,别太早就去翻标程,这样不容易达到锻炼思维,锻炼自己分析问题,快速建图的目的。

 

代码
#include<stdio.h>
#include
<string.h>
#define INF 0xfffffff
int perf[55], f[55][15];
int c[55][55], g[55][15], cc[55][55];
int pre[55];
int P, N;

int Min(int a, int b){return a < b ? a : b;}
/*这题关键是在建图,可以拆点,也可以不拆点,我采用的是不拆点,直接增加一个源点0和一个汇点N + 1,
所有input specification 不含1的机器都可以和源点相连,output specification全是1的都指向汇点
*/
void CreatGraph()
{
int i, j, k, flag;
memset(c,
0, sizeof(c));
for (i = 1; i <= N; i++){
for (j = 1; j <= N; j++){
flag
= 0;
for (k = 1; k <= P; k++){
if (i != j && g[i][k] + f[j][k] == 1){
flag
= 1;
}
}
if (!flag) c[i][j] = Min(perf[i], perf[j]);
}
}
for (i = 1; i <= N; i++){
flag
= 0;
for (j = 1; j <= P; j++){
if (f[i][j] == 1)
flag
= 1;
}
if (!flag) c[0][i] = perf[i];
flag
= 0;
for (j = 1; j <= P; j++){
if (g[i][j] == 0)
flag
= 1;
}
if (!flag) c[i][N + 1] = perf[i];
}
}

int bfs()
{
int visit[55];
int num = 1;
int i, j, min, cur;
int que[55];
que[
0] = 0;
memset(pre,
-1, sizeof(pre));
memset(visit,
0, sizeof(visit));
visit[
0] = 1;

min
= INF;
/* 这种模拟队列的方法很不错,将所有节点都只放到一个数组里,
不用更新队列,只更新队列的长度,并不断将点往后加就行了
*/
for (i = 0; i < num; i++){
cur
= que[i];
for (j = 0; j <= N + 1; j++){
if (!visit[j] && c[cur][j] > 0){
if (c[cur][j] < min)
min
= c[cur][j];
visit[j]
= 1;
que[num
++] = j;
pre[j]
= cur;

if (j == N + 1)
break;
}
}
if (j <= N + 1)
break;
}

if (i >= num)
return -1;
else
return min;
}
void Ford_Fulkerson()
{
int f, t, tt, i, j, cnt;
int maxflow = 0;
int index = 0;

memcpy(cc, c,
sizeof(c));
while ((f = bfs()) != -1){
maxflow
+= f;
t
= N + 1;
while (t != 0){
tt
= pre[t];
c[tt][t]
-= f;
c[t][tt]
+= f;
t
= tt;
}
}

cnt
= 0;
for (i = 1; i <= N; i++){
for (j = 1; j <= N; j++){
if (cc[i][j] - c[i][j] > 0)
cnt
++;
}
}

printf(
"%d %d\n", maxflow, cnt);
for (i = 1; i <= N; i++){
for (j = 1; j <= N; j++){
if (cc[i][j] - c[i][j] > 0){
printf(
"%d %d %d\n", i, j, cc[i][j] - c[i][j]);
}
}
}
}
int main()
{
int i, j;
while (scanf("%d%d", &P, &N) != EOF){
memset(perf,
0, sizeof(perf));
for (i = 1; i <= N; i++){
scanf(
"%d", &perf[i]);
for (j = 1; j <= P; j++){
scanf(
"%d", &f[i][j]);
}
for (j = 1; j <= P; j++){
scanf(
"%d", &g[i][j]);
}
}
CreatGraph();
Ford_Fulkerson();
}
return 0;
}

 

posted on 2010-06-28 21:57  ylfdrib  阅读(384)  评论(0编辑  收藏  举报