zoukankan      html  css  js  c++  java
  • [HOJ2634] How to earn more 最大权闭合子图

    Xiao Ming is an expert in computer science and technology, so he can get a lot of projects every month. The projects always bring him a lot of money, now he is thinking how to earn money as more as possible.

    Every month he can get m projects, and each project Ai will bring him Xi yuan. Although Xiao Ming is an expert, he still needs to hire some other guys to help him. Of course, the employees are not as good as Xiao Ming, for they are just good at some single aspect. So, they should work together to finish one project. There is a list shows the salary of m employees, who are labeled from 0 to m-1. Xiao Ming only hires employees, in that list, and he knows who will be needed by each project.If one employee is hired, he can join in several projects.

    Input

    The first line is an integer c shows the number of cases. For each case, the first line has two numbers m,n(m,n <=100), denoting that there is m projects and n employees on the list.The second line has m integers, which are seperated by a single blank, the ith number Ximeans the project Ai will bring Xiao Ming Xi yuan. Xi is less the 10000. The third line has n integers, which are seperated by a single blank, the ith number Yimeans the employee Bi will cost Xiao Ming Yi yuan. And the next m lines will show which part of the employees will be needed by each project. Line i is a list of the employees, who are needed by project Ai. In each line, first a number Zi shows the number of employees needed by this project. And Zi labels of the emloyees follows, which are still seperated by a sigle blank.

    Output

    You should output a single integer shows the maximun money Xiao Ming can earn in a single month. The money he can earn is equall to the money he can totally get minus the money he totally cost. You should not leave any extra blanks at the end of each line.

    Sample Input

    1
    3 5
    30 40 43
    55 17 23 22 11
    3 0 1 2
    3 1 2 3
    2 2 1

    Sample Output

    21

    Hint

    If Xiao Ming can do less project to earn more money, he will certainly do that.

    题解:

    最大权闭合子图水题,每一个工作任务有一条边 容量为输入的利润,每一个员工到汇点有一条边 容量为雇佣费,

    每一个工作任务到需要的员工有一条边,容量为INF.

    答案就是利润和-最小割

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdlib>
     6 using namespace std;
     7 const int N=405,INF=1999999999;
     8 int gi(){
     9     int str=0;char ch=getchar();
    10     while(ch>'9'||ch<'0')ch=getchar();
    11     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
    12     return str;
    13 }
    14 int n,m,s=0,T,ans=0;
    15 int num=1,head[N],q[N],dep[N];
    16 struct Lin{
    17     int next,to,dis;
    18 }a[N*N];
    19 void init(int x,int y,int dis){
    20     a[++num].next=head[x];
    21     a[num].to=y;
    22     a[num].dis=dis;
    23     head[x]=num;
    24     a[++num].next=head[y];
    25     a[num].to=x;
    26     a[num].dis=0;
    27     head[y]=num;
    28 } 
    29 bool bfs()
    30 {
    31     memset(dep,0,sizeof(dep));
    32     q[1]=s;dep[s]=1;int t=0,sum=1,u,x;
    33     while(t!=sum)
    34     {
    35         x=q[++t];
    36         for(int i=head[x];i;i=a[i].next){
    37             u=a[i].to;
    38             if(dep[u]||a[i].dis<=0)continue;
    39             dep[u]=dep[x]+1;q[++sum]=u;
    40         }
    41     }
    42     return dep[T];
    43 }
    44 int dfs(int x,int flow)
    45 {
    46     if(x==T || !flow)return flow;
    47     int u,tmp,sum=0;
    48     for(int i=head[x];i;i=a[i].next){
    49         u=a[i].to;
    50         if(a[i].dis<=0 || dep[u]!=dep[x]+1)continue;
    51         tmp=dfs(u,min(flow,a[i].dis));
    52         a[i].dis-=tmp;a[i^1].dis+=tmp;
    53         sum+=tmp;flow-=tmp;
    54     }
    55     return sum;
    56 }
    57 int maxflow(){
    58     int tot=0,tmp;
    59     while(bfs()){
    60         tmp=dfs(s,INF);
    61         while(tmp)tot+=tmp,tmp=dfs(s,INF);
    62     }
    63     return tot;
    64 }
    65 void work()
    66 {
    67     int x,k;
    68     m=gi();n=gi();
    69     T=n+m+1;
    70     for(int i=1;i<=m;i++){
    71         x=gi();init(s,i,x);
    72         ans+=x;
    73     }
    74     for(int i=1;i<=n;i++){
    75         x=gi();init(i+m,T,x);
    76     }
    77     for(int i=1;i<=m;i++){
    78         k=gi();
    79         while(k--){
    80             x=gi();init(i,x+m+1,INF);
    81         }
    82     }
    83     printf("%d
    ",ans-maxflow());
    84 }
    85 void Clear(){
    86     memset(head,0,sizeof(head));
    87     num=1;ans=0;
    88 }
    89 int main()
    90 {
    91     int TT=gi();
    92     while(TT--){
    93         work();
    94         Clear();
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    ISAPI Extension和ISAPI Filter
    Windows Debugging之二
    Windows Debugging之三
    举例一些可执行文件的后缀名
    Windows Debugging 之一
    [转]C# 日期函数
    在DataGridView中的CellEndEdit事件中删除当前行报错
    一个奇怪的问题
    [转载]如何发送和接收 Windows Phone 的 Toast 通知
    【转载】如何播放 Windows Phone 的后台音频
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6860840.html
Copyright © 2011-2022 走看看