zoukankan      html  css  js  c++  java
  • BZOJ 3280: 小R的烦恼 & BZOJ 1221: [HNOI2001] 软件开发

    3280: 小R的烦恼

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 399  Solved: 200
    [Submit][Status][Discuss]

    Description

    小R最近遇上了大麻烦,他的程序设计挂科了。于是他只好找程设老师求情。善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题。
    问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=NP,这个实验一共持续n天,第i天需要a[i]个研究生来给他搬砖。研究生毕竟也是人,所以雇佣研究生是需要钱的,机智的程设老师已经联系好了m所大学,第j所大学共有l[j]个研究生,同时雇佣这所大学的一个研究生需要p[j]元钱。
    本来程设老师满心欢喜的以为,这样捡最便宜的max{a[i]}个研究生雇来,就可以完成实验;结果没想到,由于他要求硕士生们每天工作25个小时不许吃饭睡觉上厕所喝水说话咳嗽打喷嚏呼吸空气,因此一天下来给他搬砖的所有研究生都会进入濒死状态。濒死状态的研究生,毫无疑问,就不能再进行工作了。但是机智的老师早早联系好了k家医院,第i家医院医治一个濒死的研究生需要d[i]天,并且需要q[i]元钱。

    现在,程设老师想要知道,最少花多少钱,能够在这n天中满足每天的需要呢?若无法满足,则请输出”impossible”。注意,由于程设老师良心大大的坏,所以他是可以不把濒死的研究生送去医院的!

    
    
     

    Input

           本题包含多组数据;第一行是一个数T(T<=11),表示数据组数,以下T组数据。
    对于每一组数据,第一行三个数,n,m,k;
    以下一行n个数,表示a[1]…a[n]
    接着一行2m个数,表示l[1],p[1]…l[n],p[n]
    接着一行2k个数,表示d[1],q[1]…d[n],q[n]

    Output

           对于每组数据以样例的格式输出一行,两个数分别表示第几组数据和最少钱数。

    Sample Input

    2
    3 2 1
    10 20 30
    40 90 15 100
    1 5
    3 2 1
    10 20 30
    40 90 15 100
    2 5

    Sample Output

    Case 1: 4650
    Case 2: impossible

    HINT

    样例解释:买下90块钱的那40个研究生,另外再买10个100块钱的。这样,第一天用完的10个人全部送到医院,那么他们在第三天可以继续使用;同时,第二天和第三天都用新的研究生来弥补,这样一共需要花费40*90 + 10*100 + 5*10 = 4650元。

    数据规模:

    对于30%的数据中的每组数据,

    满足n<=5,m,k<=2,其余数均小于等于100或者 

    n<=10,m,k<=10,其余数均小于等于20.

    对于100%的数据

    n,m,k<=50,其余数均小于等于100.

    Source

    网络流

    分析:

    我们把每一天拆成两个点,一个叫做A集合,一个叫做B集合...从S向A集合的每个点连一条容量为a[i]费用为0的边,从B集合中的每个点向T连边...

    然后对于每个大学,从当前大学向每个B集合中的点连一条容量为inf费用为0的边,从S向每个大学连一条容量为l[i]费用为p[i]的边...

    然后A集合中的每个点向B集合中的对应点+d[x]+1的点连一条容量为inf费用为q[x]的边,然后每个B集合中的点向下一天的点连边...

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<queue>
     6 //by NeighThorn
     7 #define inf 0x3f3f3f3f
     8 using namespace std;
     9  
    10 const int maxn=200+5,maxm=20000+5;
    11  
    12 int c,n,m,k,S,T,ans,sum,cas,cnt,w[maxm],hd[maxn],fl[maxm],to[maxm],nxt[maxm],dis[maxn],Min[maxn],vis[maxn],from[maxn];
    13  
    14 inline bool spfa(void){
    15     memset(dis,inf,sizeof(dis));
    16     memset(Min,inf,sizeof(Min));
    17     queue<int> q;q.push(S),vis[S]=1,dis[S]=0;
    18     while(!q.empty()){
    19         int top=q.front();q.pop();vis[top]=0;
    20         for(int i=hd[top];i!=-1;i=nxt[i])
    21             if(dis[to[i]]>dis[top]+w[i]&&fl[i]){
    22                 from[to[i]]=i;
    23                 dis[to[i]]=dis[top]+w[i];
    24                 Min[to[i]]=min(Min[top],fl[i]);
    25                 if(!vis[to[i]])
    26                     vis[to[i]]=1,q.push(to[i]);
    27             }
    28     }
    29     return dis[T]!=inf;
    30 }
    31  
    32 inline int find(void){
    33     for(int i=T;i!=S;i=to[from[i]^1])
    34         fl[from[i]]-=Min[T],fl[from[i]^1]+=Min[T];
    35     return ans+=Min[T],dis[T]*Min[T];
    36 }
    37  
    38 inline int mcmf(void){
    39     int res=0;
    40     while(spfa())
    41         res+=find();
    42     return res; 
    43 }
    44  
    45 inline void add(int l,int s,int x,int y){//cout<<x<<" "<<y<<" "<<s<<" "<<l<<endl;
    46     w[cnt]=l;fl[cnt]=s;to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
    47     w[cnt]=-l;fl[cnt]=0;to[cnt]=x;nxt[cnt]=hd[y];hd[y]=cnt++;   
    48 }
    49  
    50 signed main(void){
    51     scanf("%d",&cas);
    52     while(cas--){cnt=0;c++;sum=ans=0;
    53         scanf("%d%d%d",&n,&m,&k);S=0;
    54         memset(hd,-1,sizeof(hd));T=n*2+m+1;
    55         for(int i=1,x;i<=n;i++){
    56             scanf("%d",&x),add(0,x,S,i+n),add(0,x,i,T);sum+=x;
    57             if(i+1<=n)
    58                 add(0,inf,i,i+1);
    59         }
    60         for(int i=1,x,y;i<=m;i++){
    61             scanf("%d%d",&x,&y),add(y,x,S,2*n+i);
    62             for(int j=1;j<=n;j++)
    63                 add(0,inf,2*n+i,j);
    64         }
    65         for(int i=1,x,y;i<=k;i++){
    66             scanf("%d%d",&x,&y);x++;
    67             for(int j=1;j<=n;j++){
    68                 int lala=j+x;
    69                 if(lala<=n)
    70                     add(y,inf,j+n,lala);
    71             }
    72         }int lala=mcmf();
    73         printf("Case %d: ",c);
    74         if(ans!=sum)
    75             puts("impossible");
    76         else
    77             printf("%d
    ",lala);
    78     }
    79     return 0;   
    80 }

    1221: [HNOI2001] 软件开发

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1454  Solved: 805
    [Submit][Status][Discuss]

    Description

    某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

    Input

    第1行为n,a,b,f,fA,fB. 第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)

    Output

    最少费用

    Sample Input

    4 1 2 3 2 1
    8 2 1 6

    Sample Output

    38

    HINT

    Source

    分析:

    和上一题差不多...

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<queue>
     6 //by NeighThorn
     7 #define inf 0x3f3f3f3f
     8 using namespace std;
     9  
    10 const int maxn=2000+5,maxm=maxn*maxn;
    11  
    12 int n,a,b,f,fa,fb,S,T,cnt,w[maxm],hd[maxn],to[maxm],fl[maxm],nxt[maxm],dis[maxn],Min[maxn],vis[maxn],from[maxn];
    13  
    14 inline bool spfa(void){
    15     memset(dis,inf,sizeof(dis));
    16     memset(Min,inf,sizeof(Min));
    17     queue<int> q;q.push(S),vis[S]=1,dis[S]=0;
    18     while(!q.empty()){
    19         int top=q.front();q.pop();vis[top]=0;
    20         for(int i=hd[top];i!=-1;i=nxt[i])
    21             if(dis[to[i]]>dis[top]+w[i]&&fl[i]){
    22                 from[to[i]]=i;
    23                 dis[to[i]]=dis[top]+w[i];
    24                 Min[to[i]]=min(Min[top],fl[i]);
    25                 if(!vis[to[i]])
    26                     vis[to[i]]=1,q.push(to[i]);
    27             }
    28     }
    29     return dis[T]!=inf;
    30 }   
    31  
    32 inline int find(void){
    33     for(int i=T;i!=S;i=to[from[i]^1])
    34         fl[from[i]]-=Min[T],fl[from[i]^1]+=Min[T];
    35     return dis[T]*Min[T];   
    36 }
    37  
    38 inline int mcmf(void){
    39     int res=0;
    40     while(spfa())
    41         res+=find();
    42     return res; 
    43 }
    44  
    45 inline void add(int l,int s,int x,int y){
    46     w[cnt]=l;fl[cnt]=s;to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
    47     w[cnt]=-l;fl[cnt]=0;to[cnt]=x;nxt[cnt]=hd[y];hd[y]=cnt++;
    48 }
    49  
    50 signed main(void){
    51     memset(hd,-1,sizeof(hd));S=0;
    52     scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb);T=2*n+1;
    53     for(int i=1,x;i<=n;i++){
    54         scanf("%d",&x),add(0,x,S,i),add(0,x,i+n,T);
    55         if(i<n)
    56             add(0,inf,i+n,i+n+1);
    57         int lala=i+a+1,lalala=i+b+1;
    58         if(lala<=n)
    59             add(fa,inf,i,lala+n);
    60         if(lalala<=n)
    61             add(fb,inf,i,lalala+n);
    62     }add(f,inf,S,1+n);
    63     printf("%d
    ",mcmf());
    64     return 0;
    65 }//Cap ou pas cap. Pas cap.
    66 



    By NeighThorn

  • 相关阅读:
    如何在WINDOWS SERVER 2008搭建IIS7+ASP网站
    无需破解:Windows Server 2008 R2 免费使用 7200天
    渗透测试工具Nmap从初级到高级
    案例:Mysql慢SQL与加索引前后对TPS的影响
    JProfiler 9.1.1部署及使用
    内存溢出及Jvm监控工具
    MySQL监控
    Java线程及Jvm监控工具
    系统资源监控--windows
    Linux系统资源监控--linux命令、nmon和spotlight
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6264809.html
Copyright © 2011-2022 走看看