zoukankan      html  css  js  c++  java
  • 【UVA10079 训练指南】收集者的难题【最大流】

    题意:

      Bob和他的朋友从糖果包装里手机贴纸。这些朋友每人手里都有一些(可能有重复的)贴纸,并且只跟别人交换他所没有的贴纸,贴纸总是一对一交换。

     Bob比这些朋友更聪明,因为他意识到只跟别人交换自己没有的贴纸并不总是最优的。在某些情况下,换来一张重复的贴纸更划算。

     假设Bob的朋友只和Bob交换(他们之间不交换),并且这些朋友只会出让手里的重复贴纸来交换他们没有的不同贴纸。你的任务是帮助Bob算出他最终可以得到的不同贴纸的最大数量。

    分析

      建n-1个点(除Bob以外的每个人)和m个点(每个物品)从s向每个物品连边,容量为拥有该物品的数量。如果某人已经至少拥有两个物品j,那么就从i向j连边,容量为拥有的物品数-1;如果没有物品j,就从j向i连边。

     

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <queue>
      6 
      7 using namespace std;
      8 const int maxn=1000+10;
      9 const int maxm=30;
     10 const int INF=2147000000;
     11 struct Dinic{
     12     int head[maxn],Next[maxn],to[maxn],cap[maxn],flow[maxn];
     13     int sz,n,m,s,t;
     14     bool vis[maxn];
     15     int cur[maxn],d[maxn];
     16     void init(int n){
     17         this->n=n;
     18         memset(head,-1,sizeof(head));
     19         this->sz=-1;
     20     }
     21     void add_edge(int a,int b,int c){
     22         ++sz;
     23         to[sz]=b;
     24         cap[sz]=c;flow[sz]=0;
     25         Next[sz]=head[a];head[a]=sz;
     26         ++sz;
     27         to[sz]=a;
     28         cap[sz]=c;flow[sz]=c;
     29         Next[sz]=head[b];head[b]=sz;
     30     }
     31     bool BFS(){
     32         memset(vis,0,sizeof(vis));
     33         queue<int>Q;
     34         vis[s]=1;
     35         d[s]=0;
     36         Q.push(s);
     37         while(!Q.empty()){
     38             int u=Q.front();Q.pop();
     39             for(int i=head[u];i!=-1;i=Next[i]){
     40                 int v=to[i];
     41                 if(!vis[v]&&cap[i]>flow[i]){
     42                     vis[v]=1;
     43                     d[v]=d[u]+1;
     44                     Q.push(v);
     45                 }
     46             }
     47         }
     48         return vis[t];
     49    }
     50     int DFS(int x,int a){
     51         if(x==t||a==0)return a;
     52         int Flow=0,f;
     53         for(int& i=cur[x];i!=-1;i=Next[i]){
     54             int v=to[i];
     55             if(d[v]==d[x]+1&&(f=DFS(v,min(a,cap[i]-flow[i])))>0){
     56                 Flow+=f;
     57                 flow[i]+=f;
     58                 flow[i^1]-=f;
     59                 a-=f;
     60                 if(a==0)break;
     61             }
     62         }
     63         return Flow;
     64     }
     65     int Maxflow(int s,int t){
     66         this->s=s,this->t=t;
     67         int Flow=0;
     68         while(BFS()){
     69             for(int i=0;i<=n;i++)
     70              cur[i]=head[i];
     71 
     72             Flow+=DFS(s,INF);
     73         }
     74         return Flow;
     75     }
     76 }dinic;
     77 int n,m,T,kase;
     78 int main(){
     79     kase=0;
     80     scanf("%d",&T);
     81     for(int t=1;t<=T;t++){
     82         ++kase;
     83         scanf("%d%d",&n,&m);
     84         dinic.init(n+m+2);
     85         int a[maxm];
     86         dinic.s=0;dinic.t=n+m+1;
     87         for(int i=1;i<=n;i++){
     88             int num;
     89             scanf("%d",&num);
     90             memset(a,0,sizeof(a));
     91             for(int j=1;j<=num;j++){
     92                 int aa;
     93                 scanf("%d",&aa);
     94                 a[aa]++;
     95             }
     96             if(i==1){
     97                 for(int j=1;j<=m;j++){
     98                     if(a[j])
     99                     dinic.add_edge(0,n+j,a[j]);
    100                 }
    101             }else{
    102                 for(int j=1;j<=m;j++){
    103                     if(a[j]>=2){
    104                         dinic.add_edge(i,n+j,a[j]-1);
    105                     }
    106                     if(a[j]==0){
    107                         dinic.add_edge(n+j,i,1);
    108                     }
    109                 }
    110             }
    111         }
    112         for(int i=1;i<=m;i++)
    113             dinic.add_edge(i+n,dinic.t,1);
    114         int ans=dinic.Maxflow(0,dinic.t);
    115         printf("Case #%d: %d
    ",kase,ans);
    116     }
    117 return 0;
    118 }
    View Code
  • 相关阅读:
    [ThreadStatic] dosen't work with instance fields
    Java XxlJob 必知必会<续篇>
    Python 数据可视化神器—Pyecharts
    PICT 生成正交测试用例教程
    Hive 分桶表核心知识点
    Python + Flask 实现接口接收内存信息
    数据工程师:必备的 Hive 安装&交互方式技能
    JvmSandboxRepeater 配置修改详解
    JavaDubbo 接口测试
    Hadoop + Hive 数据仓库原理与架构
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9304420.html
Copyright © 2011-2022 走看看