暴力建图就好了……S->i 容量为收益,i->j+n 容量为租金,j+n->T容量为购买所花的钱。

  如果亏钱的话那么割掉的就是收益,表示不赚钱。

  如果租金大于购买所花的钱就会割掉购买的钱(因为流量限制住了……)

  表示T到死啊……copy了Hzwer……orz

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define inf 0x7fffffff
 5 using namespace std;
 6 int T,n,m,cnt=1,ans,cur[2501],q[2505],head[2505],h[2505];
 7 struct data{int to,next,v;}e[3000001];
 8 void ins(int u,int v,int w)
 9 {cnt++;e[cnt].to=v;e[cnt].v=w;e[cnt].next=head[u];head[u]=cnt;}
10 void insert(int u,int v,int w)
11 {ins(u,v,w);ins(v,u,0);}
12 bool bfs()
13 {
14      int t=0,w=1,i,now;
15      for(int i=1;i<=T;i++)h[i]=-1;
16      q[0]=h[0]=0;
17      while(t!=w)
18      {
19             now=q[t];t++;if(t==2501)t=0;
20             for(i=head[now];i;i=e[i].next)
21             {
22                   if(e[i].v&&h[e[i].to]<0)
23                         {h[e[i].to]=h[now]+1;q[w++]=e[i].to;if(w==2501)w=0;}
24              }
25      }
26      if(h[T]==-1)return 0;return 1;
27      }
28 int dfs(int x,int f)
29 {
30     if(x==T)return f;
31     int w,used=0;
32     for(int i=cur[x];i;i=e[i].next)
33     {
34             if(e[i].v&&h[e[i].to]==h[x]+1)
35             {
36                 w=f-used;
37                 w=dfs(e[i].to,min(w,e[i].v));   
38                 e[i].v-=w;if(e[i].v>0)cur[x]=i;e[i^1].v+=w;
39                 used+=w;if(used==f)return f;                      
40                 }
41             }
42     if(!used)h[x]=-1;
43     return used;
44     }
45 void dinic(){while(bfs()){for(int i=0;i<=T;i++)cur[i]=head[i];ans-=dfs(0,inf);}}
46 int main()
47 {
48     scanf("%d%d",&n,&m);
49     T=n+m+1;
50     int a,b,c,d;
51     for(int i=1;i<=n;i++)
52     {
53         scanf("%d%d",&a,&b);
54         insert(0,i,a);ans+=a;
55         for(int j=1;j<=b;j++)
56         {
57             scanf("%d%d",&c,&d);
58             insert(i,n+c,d);
59         }
60     }
61     for(int i=1;i<=m;i++)
62     {
63         scanf("%d",&a);
64         insert(n+i,T,a);
65     }
66     dinic();
67     printf("%d",ans);
68     return 0;
69 }
View Code(Hzwer)

相关文章: