网络流/最小割
暴力建图就好了……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 }
1 //BZOJ 2768 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pb push_back 12 using namespace std; 13 inline int getint(){ 14 int v=0,sign=1; char ch=getchar(); 15 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 16 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 17 return v*sign; 18 } 19 const int N=2510,M=3000000,INF=~0u>>2; 20 typedef long long LL; 21 /******************tamplate*********************/ 22 int n,m,ans; 23 struct edge{ 24 int to,v; 25 }; 26 edge E[M]; 27 int head[N],next[M],cnt; 28 void add(int x,int y,int v){ 29 E[++cnt]=(edge){y,v}; 30 next[cnt]=head[x]; head[x]=cnt; 31 E[++cnt]=(edge){x,0}; 32 next[cnt]=head[y]; head[y]=cnt; 33 } 34 int s,t,cur[N],d[N],Q[N]; 35 void init(){ 36 n=getint();m=getint(); 37 cnt=1;ans=0; 38 s=0; t=n+m+1; 39 int x,y,a,b; 40 F(i,1,n){ 41 x=getint(); y=getint(); 42 ans+=x; 43 add(s,i,x); 44 F(j,1,y){ 45 a=getint(); b=getint(); 46 add(i,n+a,b); 47 } 48 } 49 F(i,1,m){ 50 x=getint(); 51 add(n+i,t,x); 52 } 53 } 54 bool mklevel(){ 55 F(i,s,t) d[i]=-1; 56 d[s]=0; 57 int l=0,r=-1; 58 Q[++r]=s; 59 while(l<=r){ 60 int x=Q[l++]; 61 for(int i=head[x];i;i=next[i]) 62 if (d[E[i].to]==-1 && E[i].v){ 63 d[E[i].to]=d[x]+1; 64 Q[++r]=E[i].to; 65 } 66 } 67 return d[t]!=-1; 68 } 69 int dfs(int x,int a){ 70 if (x==t||a==0) return a; 71 int flow=0; 72 for(int &i=cur[x];i && flow<a;i=next[i]) 73 if (d[E[i].to]==d[x]+1 && E[i].v){ 74 int f=dfs(E[i].to,min(a-flow,E[i].v)); 75 E[i].v-=f; 76 E[i^1].v+=f; 77 flow+=f; 78 } 79 if (!flow) d[x]=-1; 80 return flow; 81 } 82 void Dinic(){ 83 while(mklevel()){ 84 F(i,s,t) cur[i]=head[i]; 85 ans-=dfs(s,INF); 86 } 87 } 88 int main(){ 89 #ifndef ONLINE_JUDGE 90 freopen("2768.in","r",stdin); 91 freopen("2768.out","w",stdout); 92 #endif 93 init();Dinic(); 94 printf("%d ",ans); 95 return 0; 96 }
1391: [Ceoi2008]order
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 746 Solved: 230
[Submit][Status][Discuss]
Description
有N个工作,M种机器,每种机器你可以租或者买过来.
每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。
现在给出这些参数,求最大利润
Input
第一行给出 N,M(1<=N<=1200,1<=M<=1200)
下面将有N块数据,每块数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序
接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000])
最后M行,每行给出购买机器的费用(其在[1,20000])
Output
最大利润
Sample Input
2 3
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
Sample Output
50