zoukankan      html  css  js  c++  java
  • POJ1149 PIGS[dinic()最大流]

    PIGS
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 12578   Accepted: 5560

    Description

    Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because he doesn't have the keys. Customers come to the farm one after another. Each of them has keys to some pig-houses and wants to buy a certain number of pigs.
    All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.
    More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
    An unlimited number of pigs can be placed in every pig-house.
    Write a program that will find the maximum number of pigs that he can sell on that day.

    Input

    The first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M and customers are numbered from 1 to N.
    The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.
    The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):
    A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.

    Output

    The first and only line of the output should contain the number of sold pigs.

    Sample Input

    3 3
    3 1 10
    2 1 2 2
    2 1 3 3
    1 2 6

    Sample Output

    7

    Source

     
     
     
     
    这题主要是构图比较难,这题以人为节点,如果有公共节点的人就作为前驱

     
     
    code:
      1 #include<iostream>
      2 using namespace std;
      3 
      4 #define MAXN 110
      5 #define inf 0x7fffffff
      6 
      7 int n,m;
      8 int cnt[1010];
      9 int pre[1010];
     10 int dis[1010];
     11 int edgenum;
     12 
     13 typedef struct edge
     14 {
     15     int from,to,cap;
     16     int next;
     17 }Edge;
     18 Edge edge[MAXN*10];
     19 int head[MAXN];
     20 
     21 void addedge(int a,int b,int c)
     22 {
     23     edge[edgenum].from=a,edge[edgenum].to=b,edge[edgenum].cap=c,edge[edgenum].next=head[a],head[a]=edgenum++;
     24     edge[edgenum].from=b,edge[edgenum].to=a,edge[edgenum].cap=0,edge[edgenum].next=head[b],head[b]=edgenum++;
     25 }
     26 
     27 int dinic(int st,int et)
     28 {
     29     int sta[1010];
     30     int que[1010];
     31     int ans=0;
     32     while(true)
     33     {
     34         memset(dis,-1,sizeof(dis));
     35         int front=0,tail=0;
     36         int u,v;
     37         dis[st]=0;
     38         que[tail++]=st;
     39         while(front<tail)
     40         {
     41             v=que[front++];
     42             for(int i=head[v];i!=-1;i=edge[i].next)
     43             {
     44                 u=edge[i].to;
     45                 if(dis[u]==-1&&edge[i].cap>0)
     46                 {
     47                     dis[u]=dis[v]+1;
     48                     que[tail++]=u;
     49                     if(u==et)
     50                     {
     51                         front=tail;
     52                         break;
     53                     }
     54                 }
     55             }
     56         }
     57         if(dis[et]==-1)
     58             break;
     59         int t=0;
     60         int s=st;
     61         while(true)
     62         {
     63             if(s!=et)
     64             {
     65                 int i;
     66                 for(i=head[s];i!=-1;i=edge[i].next)
     67                     if(edge[i].cap>0&&dis[edge[i].from]+1==dis[edge[i].to])
     68                         break;
     69                 if(i!=-1)
     70                 {
     71                     sta[t++]=i;
     72                     s=edge[i].to;
     73                 }
     74                 else
     75                 {
     76                     if(t==0)
     77                         break;
     78                     dis[edge[sta[--t]].to]=-1;
     79                     s=edge[sta[t]].from;
     80                 }
     81             }
     82             else
     83             {
     84                 int mindis=inf;
     85                 int tag;
     86                 for(int i=0;i<t;i++)
     87                     if(mindis>edge[sta[i]].cap)
     88                     {
     89                         mindis=edge[sta[i]].cap;
     90                         tag=i;
     91                     }
     92                 ans+=mindis;
     93                 for(int i=0;i<t;i++)
     94                 {
     95                     edge[sta[i]].cap-=mindis;
     96                     edge[sta[i]^1].cap+=mindis;
     97                 }
     98                 s=edge[sta[tag]].from;
     99                 t=tag;
    100             }
    101         }
    102     }
    103     return ans;
    104 }
    105 
    106 int main()
    107 {
    108     int i,j;
    109     int vst[1010];
    110     edgenum=0;
    111     memset(vst,0,sizeof(vst));
    112     memset(head,-1,sizeof(head));
    113     memset(pre,0,sizeof(pre));
    114     scanf("%d%d",&m,&n);                   //m:猪栏数量;n:人数
    115     int s=0,t=n+1;
    116     for(int i=1;i<=m;i++)
    117         scanf("%d",&cnt[i]);
    118     for(i=1;i<=n;i++)
    119     {
    120         int count,a,cap;
    121         int ans=0;
    122         scanf("%d",&count);
    123         for(j=0;j<count;j++)
    124         {
    125             scanf("%d",&a);
    126             if(!vst[a])
    127             {
    128                 ans+=cnt[a];
    129                 vst[a]=true;
    130                 pre[a]=i;
    131             }
    132             else
    133             {
    134                 addedge(pre[a],i,inf);
    135             }            
    136         }
    137         if(ans)
    138             addedge(s,i,ans);
    139         scanf("%d",&cap);
    140         addedge(i,t,cap);
    141     }
    142     printf("%d\n",dinic(s,t));
    143     return 0;
    144 }
  • 相关阅读:
    Python系列:四、Python函数--技术流ken
    Centos7破解密码的两种方法--技术流ken
    Python系列:三、流程控制循环语句--技术流ken
    Python系列:二、数据类型--技术流ken
    Python系列:一、Python概述与环境安装--技术流ken
    zabbix实现百台服务器的自动化监控--技术流ken
    学会这个删库再也不用跑路了~ --技术流ken
    五分钟彻底学会iptables防火墙--技术流ken
    Docker之使用Dockerfile创建定制化镜像(四)--技术流ken
    Docker数据卷Volume实现文件共享、数据迁移备份(三)--技术流ken
  • 原文地址:https://www.cnblogs.com/XBWer/p/2676174.html
Copyright © 2011-2022 走看看