[CEOI2008] BZOJ 1391 order-最小割

来源:互联网 发布:微距摄影师500px知乎 编辑:程序博客网 时间:2024/05/21 15:01

题目链接:右转进入题目

题目大意:请自行参考原题。

解:SB最小割竟然还卡常卡内存QwQ

第一遍MLE,第二遍TLE我也真是醉了。

从s向机器连边,容量为购买价格

从机器向任务连边,容量为租用价格

从任务向t连边,容量为收益。

统计出收益之和tot,跑一边网络流flow,tot-flow就是答案。

这个题不需要开long long。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<climits>#define INF INT_MAX#define MAXM 4000100#define MAXN 50000using namespace std;struct edges{int to,pre,cap,flow;}e[MAXM];int etop;int h[MAXN],lev[MAXN],cur[MAXN];bool vis[MAXN];queue<int> q;int add_edge(int u,int v,int c){etop++;e[etop].cap=c;e[etop].flow=0;e[etop].to=v;e[etop].pre=h[u];h[u]=etop;return 0;}bool bfs(int s,int t){memset(lev,0,sizeof(lev));memset(vis,false,sizeof(vis));while(!q.empty()) q.pop();q.push(s);vis[s]=true;lev[s]=1;while(!q.empty()){int x=q.front();q.pop();for(int i=h[x];i;i=e[i].pre)if(!vis[e[i].to]&&e[i].cap-e[i].flow){vis[e[i].to]=true;lev[e[i].to]=lev[x]+1;q.push(e[i].to);}}return vis[t];}int dfs(int s,int t,int a){if(s==t||!a) return a;int flow=0,f;for(int &i=cur[s];i;i=e[i].pre)if(lev[e[i].to]==lev[s]+1&&(f=dfs(e[i].to,t,min(a,e[i].cap-e[i].flow)))>0){flow+=f;a-=f;e[i].flow+=f;e[((i-1)^1)+1].flow-=f;if(!a) break;}return flow;}int main(){int n,m;scanf("%d%d",&n,&m);int s=0,t=m+n+1;int totans=0;for(int i=1;i<=n;i++){int k,c;scanf("%d%d",&c,&k);totans+=c;add_edge(i,t,c);add_edge(t,i,0);while(k--){int id;scanf("%d%d",&id,&c);add_edge(id+n,i,c);add_edge(i,id+n,0);}}for(int i=1;i<=m;i++){int c;scanf("%d",&c);add_edge(s,i+n,c);add_edge(i+n,s,0);}int flow=0;while(bfs(s,t)){for(int i=s;i<=t;i++)cur[i]=h[i];flow+=dfs(s,t,INF);}printf("%d\n",totans-flow);return 0;}


0 0
原创粉丝点击