加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 3759 最大流

(2010-07-28 12:48:42)
标签:

poj

pku

3759

最大流

it

分类: 网络流

题目描述:

n个程序,m个服务器,

每个程序i有它最大消耗的CPU值ni。

每个服务器有一个最大可承载CPU值,每个服务器可以运行n个程序中的某一些(运行的程序在此服务器消耗的CPU值小于等于ni)。

1:要求每个程序i在所有服务器上运行占用CPU和小于ni。

2:假设每个程序分在k个服务器上运行(运行表示CPU消耗量不为0),则这k个服务器至多只能有一个不是满载运行。

在以上条件下:

使所有服务器消耗CPU总和最大。

解题报告:

根据bfs的性质,可以知道,一定是从一个点(程序或服务器)开始,把它的增广路找完了才去找下一个,所以就保证了最多只有一个不满载的(把样例画画图一下就出来了)。

所以,我们大可不用去关心第二个条件,只要让CPU总和最大就可以了,朴素的最大流。

代码如下:

#include<iostream>
using namespace std;
#define size 500
#define Max 0x7fffffff
int cap[size][size],s,t,n;
int queue[size],head,tail, Flow,prev[size];
bool findload()      //bfs找增广路径
{
 int i, tmp;
 memset(prev,-1,sizeof(prev));
 head = tail = 0;;
 queue[tail++] = s;
 prev[s] = s;
 while(head < tail)
 {
  tmp = queue[head++];
  for(i = 1; i <= n; i++)
   if(prev[i] == -1 && cap[tmp][i] > 0)
   {
    prev[i] = tmp;
    if (i == t) return true;
    queue[tail++] = i;
   }
 }
 return false;
}
int maxflow()
{
    Flow = 0;
 while(findload())
 {
  int min = Max;
  for(int i = t; i != s; i = prev[i])  //增广路径中的最小可通过流
   if(min > cap[prev[i]][i])
    min = cap[prev[i]][i];
  for(int i = t; i != s; i = prev[i])//调整路径上的流
  {
   cap[prev[i]][i] -= min;
   cap[i][prev[i]] += min;
  }
  Flow += min;   //最大流累加
 }
 return Flow;
}
int nn, mm, x, y[210][210];
int main()
{
    scanf("%d%d", &nn, &mm);
    s = nn + mm + 1; n = t = nn + mm + 2;
    memset(cap, 0, sizeof(cap));
    for(int i = 1; i <= nn; i++)
    {
        scanf("%d", &x);
        cap[s][i] = x;
    }
    for(int i = 1; i <= mm; i++)
    {
        scanf("%d", &x);
        cap[i + nn][t] = x;
        y[i][0] = 1;
        int k; scanf("%d", &k);
        for(int j = 0; j < k; j++)
        {
            scanf("%d", &x);
            y[i][y[i][0]++] = x + 1;
            cap[x + 1][i + nn] = cap[s][x + 1];
        }
    }
    printf("%d\n", maxflow());
    for(int i = 1; i <= mm; i++)
    {
        for(int j = 1; j < y[i][0]; j++)
        {
            printf("%d", cap[i + nn][y[i][j]]);
            if (j < y[i][0] - 1) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有