HDU 4322 最大费用最大流 2012 Multi-University Training Contest 3

来源:互联网 发布:ecshop淘宝客采集插件 编辑:程序博客网 时间:2024/05/18 14:43

            初学网络流,什么都不懂只会套模板的菜鸟啊。比赛时看了这道题就觉得是网络流,由于水平太菜,构图不会。赛后看了题解,决定A掉。

            题意:M颗糖分给N个孩纸,每个孩纸有自己喜欢的糖和不喜欢的糖(记1,0),如果得到喜欢的糖则兴奋值加k,得到不喜欢的也加1,如果兴奋值>=b[i],则这个孩纸会灰常高兴,问是否可以让所有孩纸都高兴。

           思路:最大费用最大流,我们先对所有孩纸喜欢的糖果进行处理,有不足的话就让不喜欢的糖去填补,这样的话,如果一个孩纸的兴奋值>=b[i],则超出的部分就浪费掉了,所以我们用网络流去控制流量。

           建模:每颗糖果与源点连一条容量为1,费用为0的边, add(s,i,1,0);

                     每颗糖与喜欢的孩纸连一条容量为1,费用为0的边 add(i,j+n,1,0);

                     每个孩纸与汇点连一条容量为b[i]/k,费用为k的边,add(j+n,t,b[i]/k,k);

                     如果b[i]%k>1则,孩纸与汇点再连一条容量为1,费用为b[i]%k的边(因为b[i]%k==1的话,我们可以用不喜欢的糖去填,所以连边没有意义,会造成浪费);

         开始只会最小费用流,由于对网络流理解比较菜,改模板就遇到困难了,要把dist初始化为-1,spfa寻找最大费用判断语句改为dist[v]<dist[u]+cost[i]即可因为改不好TLE了无数次,另外不知道什么原因,矩阵用单变量存储会wa掉,要用二维数组存储。

        代码:

   

#include<stdio.h>#include<string.h>#include<algorithm>#define maxn 31#define maxm 8888#define inf 0x3f3f3f3f#define clr(a,b) memset(a,b,sizeof(a))using namespace std;int e,ev[maxm],next[maxm],head[maxn],f,c;int cost[maxm],dist[maxn],cap[maxm],b[maxn];int pnt[maxn],road[maxn],q[maxn+10],bg,ed;bool vis[maxn];void init() {e=0;clr(head,-1);}void add(int u,int v,int f,int c){    ev[e]=v;cap[e]=f;cost[e]=c;next[e]=head[u];head[u]=e++;    ev[e]=u;cap[e]=0;cost[e]=-c;next[e]=head[v];head[v]=e++;}bool spfa(int s,int t,int N){    for(int i=0;i<=N;i++) dist[i]=-1,vis[i]=0;    bg=ed=0;    pnt[s]=s;q[ed++]=s;    dist[s]=0;    while(bg!=ed)    {        int u=q[bg++];vis[u]=0;        if(bg==maxn) bg=0;        for(int i=head[u];~i;i=next[i])        {            if(cap[i]<=0) continue;            int v=ev[i];            if(dist[v]<dist[u]+cost[i])            {                dist[v]=dist[u]+cost[i];                pnt[v]=u;road[v]=i;                if(!vis[v])                {                    q[ed++]=v;vis[v]=1;                    if(ed==maxn) ed=0;                }            }        }    }    return dist[t]!=-1;}void maxcost(int s,int t,int N,int &f,int &c){    c=f=0;    while(spfa(s,t,N))    {        int minf=inf;        for(int u=t;u!=s;u=pnt[u])            minf=min(minf,cap[road[u]]);        for(int u=t;u!=s;u=pnt[u])        {            cap[road[u]]-=minf;            cap[road[u]^1]+=minf;        }        f+=minf;        c+=minf*dist[t];    }}int main(){    //freopen("D:/d.txt","r",stdin);    int s,t,sum,g[maxn][maxn],n,m,k,ca,cas=1;    scanf("%d",&ca);    while(ca--)    {        init();        scanf("%d%d%d",&n,&m,&k);        s=0,t=n+m+1,sum=0;        for(int i=1;i<=m;i++)        {            scanf("%d",&b[i]);            sum+=b[i];        }        for(int i=1;i<=n;i++)          add(s,i,1,0);        for(int i=1;i<=m;i++)        {            if(b[i]>=k) add(i+n,t,b[i]/k,k);            if(b[i]%k>1)add(i+n,t,1,b[i]%k);            for(int j=1;j<=n;j++)            {                scanf("%d",&g[i][j]);                if(g[i][j]) add(j,i+n,1,0);            }        }        maxcost(s,t,n+m+2,f,c);        printf("Case #%d: ",cas++);        if(c+n-f>=sum) printf("YES\n");        else printf("NO\n");    }    return 0;}

原创粉丝点击