• poj 3281 Dining 网络流-最大流-建图的题


    题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱)

    输入数据有N,F,D,表示牛的个数,食物的数量,饮料的数量

    接着输出N行表示N个牛的数据

    每个牛的数据前2个是Fi和Di表示第i个牛喜欢吃的食物种数和饮料种数,接着输出Fi个食物的编号和Di个食物的编号

    ok题意就是这样,这题主要考的是建图

    需要把牛拆点,一分为二 图应该是 这种形式      源点 ->饮料->牛->牛->食物->汇点  当然食物和饮料的位置可以互换   牛->牛的边,只能是自己和自己有一条边而且边权为一 而且源点和一个饮料之间有且仅有一条边,边权为一,这样就保证了每个饮料只能被一头牛喝,同理 每个食物与汇点之间有且仅有一条边而且边权为一


    既然图建好了那么就套模板吧

    我的代码,注释还算详细吧

    /*********
    PRO: POJ 3281
    TIT: Dining
    DAT: 2013-08-14
    AUT: UKean
    EMA: huyocan@163.com
    *********/
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define  INF 1e9
    using namespace std;
    queue<int> que;//广搜需要使用的队列
    int M;//M是点数
    int s,t;//源点和汇点
    int flow[505][505];//残流量
    int p[505];//广搜记录路径的父节点数组
    int a[505];//路径上的最小残量
    int cap[505][505];//容量网络
    int ans;//最大流
    int read()
    {
    	int N,F,D,temp;
    	if(!(cin>>N>>F>>D)) return 0;
    	memset(cap,0,sizeof(cap));
    	s=0;//超级源点
    	t=M=F+N+N+D+1;//超级汇点
    	for(int i=1;i<=N;i++)//1到D是饮料 D+1到N+D是牛,N+D+1到N+D+N是牛 2*N+D+1到2*N+F+D是食物
    	{
    		cap[i+D][N+i+D]=1;//牛与牛之间建立一条边
    		int fnum,dnum;
    		cin>>fnum>>dnum;//第i头牛喜欢的食物数和饮料数
    		for(int j=0;j<fnum;j++)//
    		{
    			cin>>food;
    			cap[D+i+N][D+2*N+food]+=1;//牛与食物之间建立一条边
    			cap[D+2*N+food][t]=1;//食物与会点之间建立一条边,但是边权只能为一,因为一个食物只能被选一次
    		}
    		for(int j=0;j<dnum;j++)
    		{
    			int drink;cin>>drink;
    			cap[s][drink]=1;//饮料与会点之间建立一条边,但是边权只能为一,因为一个饮料只能被选一次
    			cap[drink][D+i]+=1;//饮料与牛之间建立一条边
    		}
    	}
    	return 1;
    }
    
    int deal()//增广路算法就不具体解释了,详细的解释可以看我关于网络流的第一篇博客  
    //   http://blog.csdn.net/hikean/article/details/9918093 
    {
    	memset(flow,0,sizeof(flow));
    	ans=0;
    	while(1)
    	{
    		memset(a,0,sizeof(a));
    		a[s]=INF;
    		que.push(s);
    		while(!que.empty())
    		{
    			int u=que.front();que.pop();
    			for(int v=0;v<=M;v++)
    			if(!a[v]&&cap[u][v]-flow[u][v]>0)
    			{
    				p[v]=u;
    				que.push(v);
    				a[v]=min(a[u],cap[u][v]-flow[u][v]);
    			}
    		}
    		if(a[t]==0) break;
    		for(int u=t;u!=s;u=p[u])
    		{
    			flow[p[u]][u]+=a[t];
    			flow[u][p[u]]-=a[t];
    		}
    		ans+=a[t];
    	}
    	cout<<ans<<endl;
    	return ans;
    }
    int main()
    {
    	//freopen("in.txt","r",stdin);
    	//freopen("out.txt","w",stdout);
    	while(read())
    		deal();
    	return 0;
    }
    

    另外附2组数据



    4 6 9 13 32 40 3 5 29 32 41 45
    3 2 18 20 31 28 52
    3 5 10 17 35 12 19 40 53 55
    3 8 2 8 31 3 8 9 18 21 42 47 55
    5 7 8 11 14 29 40 4 7 13 17 28 45 49
    5 2 11 18 28 32 35 27 29
    3 8 7 38 40 4 11 17 26 28 30 38 55
    3 2 5 9 25 12 33
    4 5 2 13 23 24 3 12 34 52 59
    4 3 1 21 30 35 6 23 40
    2 9 30 31 18 23 27 31 34 38 51 57 58
    6 6 8 13 18 28 30 32 1 30 41 50 57 59
    4 5 5 19 28 32 38 42 43 44 59
    3 3 4 21 32 13 16 33
    4 6 12 15 20 28 5 6 21 38 43 57
    2 2 6 17 36 48
    3 3 29 32 35 2 6 54
    1 4 18 11 19 48 55
    2 3 2 35 8 10 57
    2 10 4 29 3 4 5 13 17 20 31 40 41 59
    3 3 7 12 17 35 45 57
    3 2 20 21 24 2 6
    5 5 5 16 18 29 35 25 30 36 39 41
    4 5 5 27 33 35 33 35 45 49 55
    0 6 7 18 29 34 46 60
    3 11 27 31 39 11 14 23 25 29 32 36 40 44 48 56
    1 5 21 5 17 25 47 49


    4 3 3
    2 2 1 2 3 1
    2 2 2 3 1 2
    2 2 1 3 1 2
    2 1 1 3 3



    答案是 29  3

  • 相关阅读:
    一、maven的安装及配置
    Mybatis分页助手PageHelper
    $('#itemAddForm').form('reset');重置表单是报错?
    个人遇到的几种Date类型处理方式
    eclipse中tomcat的add and remove找不到项目
    print,printf,println的区别,以及 , , 的区别
    linux权限问题,chmod命令
    前后端分离怎么部署
    linux安装jdk
    springboot jar包方式部署
  • 原文地址:https://www.cnblogs.com/riskyer/p/3258265.html
Copyright © 2020-2023  润新知