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

ZOJ 3305 拆点 最大流

(2010-09-21 17:06:54)
标签:

zoj

3305

拆点

最大流

it

分类: 网络流

题目描述:现有N个(16)不同的材料,编号从1~N。

有M(50000)个模型,每个模型都需要一些材料才能完成。

给你每个模型需要的材料是什么。

问你最多能完成多少个模型。(注意,N个材料每个仅能用一次)。

解题报告:

由于每个材料只能用一次,所以最多也就是能个完成16个模型了。

建图:

N个材料拆点,i号材料为点i和点i+n

连接所有的点i和i+n,容量1。(限制每个点仅用一次)

对于每个模型需要的材料 排序 后,为x1,x2 …… xm

源点s = 0,连接x1

汇点t = n + n + 1, 和xm(最后一个连接)

其余的xi + n连接xi + 1.

这样就保证s所连接的是起点,t所连接的是终点。

并且每一个从s到t的通路都是一个模型的方案。

同时每个点由于拆点限制了只能用一次。

所以最大流就是答案。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define size 50
#define Max 0x1fffffff
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 = 0; 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 a, b, jeo[16], cnt;
int main()
{
    while(scanf("%d%d", &a, &b) != EOF)
    {
        memset(cap, 0, sizeof(cap));
        s = 0, t = a + a + 1; n = t + 1;
        for(int i = 1; i <= a; i++) cap[i][i + a] = 1;
        while(b--)
        {
            int tmp; scanf("%d", &tmp);
            for(int i = 0; i < tmp; i++)scanf("%d", &jeo[i]);
            sort(jeo, jeo + tmp);
            cap[s][jeo[0]] = 1;cap[jeo[tmp - 1]][t] = 1;
            for(int i = 0; i < tmp - 1; i++)
                cap[jeo[i] + n][jeo[i + 1]] = 1;
        }
        printf("%d\n", maxflow());
    }
    return 0;
}

0

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

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

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

新浪公司 版权所有