【HDU4322】Candy

                                             Candy

                      Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
                                           Total Submission(s): 2381    Accepted Submission(s): 721

 

Problem Description

There are N candies and M kids, the teacher will give this N candies to the M kids. The i-th kids for the j-th candy has a preference for like[i][j], if he like the sugar, like[i][j] = 1, otherwise like[i][j] = 0. If the i-th kids get the candy which he like he will get K glad value. If he or she do not like it. He will get only one glad value. We know that the i-th kids will feel happy if he the sum of glad values is equal or greater than B[i]. Can you tell me whether reasonable allocate this N candies, make every kid feel happy.

Input

The Input consists of several cases .The first line contains a single integer t .the number of test cases.
For each case starts with a line containing three integers N, M, K (1<=N<=13, 1<=M<=13, 2<=K<=10)
The next line contains M numbers which is B[i](0<=B[i]<=1000). Separated by a single space.
Then there are M*N like[i][j] , if the i-th kids like the j-th sugar like[i][j]=1 ,or like[i][j]=0.

Output

If there have a reasonable allocate make every kid feel happy, output "YES", or "NO".

Sample Input

 

2

3 2 2

2 2

0 0 0

0 0 1

3 2 2

2 2

0 0 0

0 0 0

Sample Output

 

Case #1: YES

Case #2: NO

Hint

Give the first and second candy to the first kid. Give the third candy to the second kid. This allocate make all kids happy. 

 

解析:

       最大费用最大流。
       偷懒挂个链接:Candy

 

代码:
 

#include <bits/stdc++.h>
using namespace std;

const int inf=1e9;
const int Max=300;
int t,n,m,k,ans1,ans2,sum,size=1,S,T,head,tail;
int f[50][50],dis[Max],first[Max],tmp[Max],b[Max],p[Max],vis[Max],v[Max];
struct shu{int to,next,len,c;}; //c费用 
shu edge[Max];

inline void clean()
{
    size=1,sum=ans1=ans2=0;
    memset(f,0,sizeof(f));
    memset(first,0,sizeof(first));
    memset(v,0,sizeof(v));
}

inline void build(int x,int y,int z,int c)
{
    edge[++size].next=first[x],first[x]=size,edge[size].to=y,edge[size].len=z,edge[size].c=c;
    edge[++size].next=first[y],first[y]=size,edge[size].to=x,edge[size].len=0,edge[size].c=-c;
}

inline void pre()
{
    for(int i=1;i<=n;i++) build(S,i,1,0);
    for(int i=1;i<=m;i++)
    {
      build(i+n,T,b[i]/k,-k);
      if(b[i]%k>1) build(i+n,T,1,-b[i]%k);
    }
    for(int i=1;i<=m;i++)
      for(int j=1;j<=n;j++)
        if(f[i][j]) build(j,i+n,1,0);
}

inline int spfa()
{
   memset(dis,0x3f,sizeof(dis)),memset(vis,0,sizeof(vis));
   head=0,tail=1;dis[S]=0;p[1]=S,vis[S]=1;
   while(head<=tail)
   {
     int point=p[++head];
     vis[point]=0;
     for(int u=first[point];u;u=edge[u].next)
     {
       if(edge[u].len > 0 && dis[point]+edge[u].c < dis[edge[u].to])
       {
            dis[edge[u].to]=dis[point]+edge[u].c;
            if(!vis[edge[u].to])
            {
              vis[edge[u].to]=1;
              p[++tail]=edge[u].to;
            }
       }
     }
   }
   if(dis[T] == dis[100]) return 0;
   else return 1;
}

inline int dinic(int point,int flow)
{
   if(point == T) return flow;
   v[point]=1;
   int sum=0;
   for(int &u=tmp[point];u;u=edge[u].next)
        if(!v[edge[u].to] && dis[edge[u].to] == dis[point] + edge[u].c && edge[u].len > 0)
        {
          int minn=dinic(edge[u].to,min(flow-sum,edge[u].len));
       ans2+=minn*edge[u].c;
          edge[u].len-=minn;
          edge[u^1].len+=minn;
          sum+=minn;
       if(flow-sum == 0) break;
     }
   v[point]=0;
   return sum;
}

inline void solve()
{
    while(spfa())
    {
      memcpy(tmp,first,sizeof(first));
      ans1+=dinic(S,inf);
    }
}

int main()
{
    scanf("%d",&t);
    for(int q=1;q<=t;q++)
    {
      printf("Case #%d: ",q);
      clean();
      scanf("%d%d%d",&n,&m,&k);T=30;
      for(int i=1;i<=m;i++) scanf("%d",&b[i]),sum+=b[i];
      for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++) scanf("%d",&f[i][j]);
      pre();
      solve();
      if(sum+ans2<=n-ans1) printf("YES\n");
      else printf("NO\n");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值