zoukankan      html  css  js  c++  java
  • uva 10779 Collectors Problem

    题目描述:

    Bob和他的朋友从糖果包装里收集贴纸。Bob和他的朋友总共n人。共有m种不同的贴纸。
    每人手里都有一些(可能有重复的)贴纸,并且只跟别人交换他所没有的贴纸。贴纸总是一对一交换。
    Bob比这些朋友更聪明,因为他意识到只跟别人交换自己没有的贴纸并不总是最优的。在某些情况下,换来一张重复的贴纸更划算。
    假设Bob的朋友只跟Bob交换(他们之间不交换),并且这些朋友只会出让手里的重复贴纸来交换他们没有的不同贴纸。你的任务是帮助Bob算出他最终可以得到的不同贴纸的最大数量。
    2 ≤ n ≤ 10, 5 ≤ m ≤ 25

    solution:

    网络流最大流

    把每一个糖纸建成一个节点,一共有m个

    除了bob的n-1个人(我们定义他们叫sbzyf)建成n-1个节点

    对于第i种糖纸,如果sbzyf有v个

    有1个:则不连边

    有0个:则他可以接受1个,就把第i个糖纸的节点向他连一条 1 的边

    有v>1个:则他可以给v-1个,就把他向第i个糖纸连 v-1 的边

    (ps:再输入的时候  把j打成了i  调了半个小时.....)

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #define mem(a,b) memset(a,b,sizeof(a))
      5 using namespace std;
      6 const int INF=(1<<31)-1;
      7 inline int minn(int a,int b){return a<b?a:b;}
      8 struct son
      9 {
     10     int v,next,w,u;
     11 };
     12 son a1[50001];
     13 int first[50001],e;
     14 
     15 void addbian(int u,int v,int w)
     16 {
     17     a1[e].u=u;
     18     a1[e].v=v;
     19     a1[e].w=w;
     20     a1[e].next=first[u];
     21     first[u]=e++;
     22 }
     23 
     24 int t,n,m;
     25 int u,o,p;
     26 int S,T;
     27 int ji[27];
     28 int dep[201];
     29 
     30 int dui[1000001],he,en;
     31 inline void clear(){he=1;en=0;}
     32 inline void push(int x){dui[++en]=x;}
     33 inline int top(){return dui[he];}
     34 inline void pop(){++he;}
     35 inline bool empty(){return en>=he?0:1;}
     36 
     37 int bfs()
     38 {
     39     mem(dep,0);
     40     clear();
     41     dep[S]=1;push(S);
     42     while(!empty())
     43     {
     44         int now=top();pop();
     45         //printf("now=%d
    ",now);
     46         for(int i=first[now];i!=-1;i=a1[i].next)
     47         {
     48             int temp=a1[i].v;
     49             if(dep[temp]||!a1[i].w)continue;
     50             dep[temp]=dep[now]+1;
     51             push(temp);
     52             if(temp==T)return 1;
     53         }
     54     }
     55     return 0;
     56 }
     57 
     58 int dfs(int x,int val)
     59 {
     60     //printf("x=%d
    ",x);
     61     if(x==T)return val;
     62     int val2=val,k;
     63     for(int i=first[x];i!=-1;i=a1[i].next)
     64     {
     65         int temp=a1[i].v;
     66         if(dep[temp]!=dep[x]+1||!a1[i].w||!val2)continue;
     67         k=dfs(temp,minn(val2,a1[i].w));
     68         if(!k){dep[temp]=0;continue;}
     69         a1[i].w-=k;a1[i^1].w+=k;val2-=k;
     70     }
     71     return val-val2;
     72 }
     73 
     74 int Dinic()
     75 {
     76     int ans=0;
     77     while(bfs())
     78       ans+=dfs(S,INF);
     79     return ans;
     80 }
     81 
     82 void chu()
     83 {
     84     mem(a1,0);
     85     mem(first,-1);
     86     e=0;
     87 }
     88 
     89 void out11()
     90 {
     91     printf("
    ");
     92     for(int i=S;i<=T;++i)
     93     {
     94         printf("i=%d
    ",i);
     95         for(int j=first[i];j!=-1;j=a1[j].next)
     96           printf("%d ",a1[j].v);
     97         printf("
    ");
     98     }
     99     printf("
    ");
    100 }
    101 
    102 int main(){
    103     //freopen("1.txt","r",stdin);
    104     scanf("%d",&t);
    105     for(int l=1;l<=t;++l)
    106     {
    107         chu();
    108         scanf("%d%d",&n,&m);
    109         S=0;T=n+m;
    110         
    111         mem(ji,0);
    112         scanf("%d",&u);
    113         for(int i=1;i<=u;++i){scanf("%d",&o);++ji[o];}
    114         for(int i=1;i<=m;++i)
    115             if(ji[i])
    116             {
    117                 addbian(S,i,ji[i]);
    118                 addbian(i,S,0);
    119             }
    120         
    121         for(int i=1;i<n;++i)
    122         {
    123             mem(ji,0);
    124             scanf("%d",&u);
    125             for(int j=1;j<=u;++j)
    126             {
    127                 scanf("%d",&o);
    128                 ++ji[o];
    129             }
    130             
    131             /*printf("
    ");
    132             printf("i=%d
    ",i);
    133             for(int j=1;j<=m;++j)
    134               printf("%d ",ji[j]);
    135             printf("
    ");*/
    136             
    137             for(int j=1;j<=m;++j)
    138             {
    139                 if(!ji[j])
    140                 {
    141                     addbian(j,i+m,1);
    142                     addbian(i+m,j,0);
    143                 }
    144                 else
    145                   if(ji[j]>1)
    146                   {
    147                         addbian(i+m,j,ji[j]-1);
    148                         addbian(j,i+m,0);
    149                     }
    150             }
    151         }
    152         
    153         for(int i=1;i<=m;++i)
    154         {
    155             addbian(i,T,1);
    156             addbian(T,i,0);
    157         }
    158         
    159         //out11();
    160         
    161         //cout<<0;
    162         printf("Case #%d: %d
    ",l,Dinic());
    163         //cout<<1;
    164     }
    165     //while(1);
    166     return 0;
    167 }
    code
  • 相关阅读:
    urllib模块常用方法
    python Apscheduler持久化
    Java 递归(深度优先)寻找迷宫最短路径
    Java 访问修饰符
    Java 多态的一道例题
    性能测试基础(二)
    Update DataReader
    VS.Php Beta 4
    Free ASP.NET Web Development Tool
    使用 Microsoft .NET 的企业解决方案模式
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7256933.html
Copyright © 2011-2022 走看看