HDU - 5855 Less Time, More profit 最大权闭合子图 + 二分
2017-09-13 17:02
369 查看
传送门:HDU 5855
题意:
有n个工厂,m个商店
每个工厂有建造时间ti,花费payi
每个商店和k个工厂有关,如果这k个工厂都建造了,那么能获利proi
问你求收益(∑pro−∑pay)≥L时,首先满足时间t最小,其次是收益p最大
显然要满足最长的时间最短要二分,我们将商店向工厂连边,由于商店需要的所有工厂都要建设才能使商店获利,因此显然最后选择出来的
商店和工厂的点集是一个闭合子图,那么题目自然就是求最大权闭合子图啦,剩下的就是老套路了。
第一次自己做出来比赛题中的网络流,虽说是个签到题吧,但是还是美滋滋啊。
代码:
题意:
有n个工厂,m个商店
每个工厂有建造时间ti,花费payi
每个商店和k个工厂有关,如果这k个工厂都建造了,那么能获利proi
问你求收益(∑pro−∑pay)≥L时,首先满足时间t最小,其次是收益p最大
显然要满足最长的时间最短要二分,我们将商店向工厂连边,由于商店需要的所有工厂都要建设才能使商店获利,因此显然最后选择出来的
商店和工厂的点集是一个闭合子图,那么题目自然就是求最大权闭合子图啦,剩下的就是老套路了。
第一次自己做出来比赛题中的网络流,虽说是个签到题吧,但是还是美滋滋啊。
代码:
//ISAP int #include <iostream> #include <cstdio> #include <cstring> #include <queue> #define ll long long #define MAXN 10005 #define inf 0x3f3f3f3f using namespace std; typedef pair<int, int> P; int n;//实际建图点数(最好比图中总点数大一点) struct Edge{ int v,next; int cap,flow; }edge[MAXN*100]; int cur[MAXN],pre[MAXN],gap[MAXN],path[MAXN],dep[MAXN]; int cnt=0;//实际存储总边数 void init() { cnt=0; memset(pre,-1,sizeof(pre)); } void add(int u,int v,int w,int rw=0)//加边 有向图三个参数,无向图四个 { edge[cnt].v=v; edge[cnt].cap=w; edge[cnt].flow=0; edge[cnt].next=pre[u]; pre[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=rw; edge[cnt].flow=0; edge[cnt].next=pre[v]; pre[v]=cnt++; } bool bfs(int s,int t)//其实这个bfs可以融合到下面的迭代里,但是好像是时间要长 { memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0]=1; dep[t]=0; queue<int>q; while(!q.empty()) q.pop(); q.push(t);//从汇点开始反向建层次图 while(!q.empty()) { int u=q.front(); q.pop(); for(int i=pre[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dep[v]==-1&&edge[i^1].cap>edge[i^1].flow)//注意是从汇点反向bfs,但应该判断正向弧的余量 { dep[v]=dep[u]+1; gap[dep[v]]++; q.push(v); //if(v==s)//感觉这两句优化加了一般没错,但是有的题可能会错,所以还是注释出来,到时候视情况而定 //break; } } } return dep[s]!=-1; } int isap(int s,int t) { bfs(s,t); memcpy(cur,pre,sizeof(pre)); int u=s; path[u]=-1; int ans=0; while(dep[s]<n)//迭代寻找增广路 { if(u==t) { int f=inf; for(int i=path[u];i!=-1;i=path[edge[i^1].v])//修改找到的增广路 f=min(f,edge[i].cap-edge[i].flow); for(int i=path[u];i!=-1;i=path[edge[i^1].v]) { edge[i].flow+=f; edge[i^1].flow-=f; } ans+=f; u=s; continue; } bool flag=false; int v; for(int i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(dep[v]+1==dep[u]&&edge[i].cap-edge[i].flow) { cur[u]=path[v]=i;//当前弧优化 flag=true; break; } } if(flag) { u=v; continue; } int x=n; if(!(--gap[dep[u]]))return ans;//gap优化 for(int i=pre[u];i!=-1;i=edge[i].next) { if(edge[i].cap-edge[i].flow&&dep[edge[i].v]<x) { x=dep[edge[i].v]; cur[u]=i;//常数优化 } } dep[u]=x+1; gap[dep[u]]++; if(u!=s)//当前点没有增广路则后退一个点 u=edge[path[u]^1].v; } return ans; } struct plant{ int pay, t; }p[220]; int val[220]; int N, M, L, source, sink; vector<int> shop[220]; int build(int up) { bool flag = 0; int sum = 0; for(int i = 1; i <= M; i++) { flag = 0; for(int j = 0; j < shop[i].size(); j++) { if(p[shop[i][j]].t > up) flag = 1; } if(flag) continue; add(source, i, val[i]); sum += val[i]; for(int j = 0; j < shop[i].size(); j++) { add(i, M + shop[i][j], inf); } } for(int i = 1; i <= N; i++) { add(i + M, sink, p[i].pay); } return sum; } P solve(int up) { source = 0, sink = N + M + 1; n = sink + 1; int l = 0, r = up + 1, mid, sum, tmp, max_flow; while(l <= r) { mid = (l + r) >> 1; init(); sum = build(mid); tmp = isap(source, sink); if(sum - tmp >= L) r = mid - 1, max_flow = sum - tmp; else l = mid + 1; } return P(r + 1, max_flow); } int main() { int T, kase = 1; int k, u, v; cin >> T; while(T--) { int up = 0; scanf("%d %d %d", &N, &M, &L); for(int i = 0; i <= M; i++) shop[i].clear(); for(int i = 1; i <= N; i++) { scanf("%d %d", &p[i].pay, &p[i].t); up = max(up, p[i].t); } for(int i = 1; i <= M; i++) { scanf("%d", val + i); scanf("%d", &k); while(k--) { scanf("%d", &u); shop[i].push_back(u); } } P ans = solve(up); if(ans.first > up) printf("Case #%d: impossible\n", kase++); else printf("Case #%d: %d %d\n", kase++, ans.first, ans.second); } }
相关文章推荐
- HDU 5855 Less Time, More profit 【最大流-最大权闭合子图】
- hdu 5855 Less Time, More profit(最大权闭合子图)
- HDU 5855 Less Time, More profit(最大权闭合子图)
- HDU 5855 Less Time, More profit(最大权闭合子图)
- hdu-5855 Less Time, More profit(最大权闭合子图)
- [HDOJ5855]Less Time, More profit(最大权闭合子图,二分,最大流)
- HDU-5855 Less Time, More profit(最大权闭合图+二分)
- HDU 5855 Less Time, More profit 最大权闭合子图
- hdu_5855_Less Time, More profit(二分+最大权闭合图)
- HDU 5855 Less Time, More profit(最大权闭合图)
- hdu 5855 Less Time, More profit【二分+最大权闭包--最大流Dinic】
- 【HDU 5855】Less Time, More profit(网络流、最小割、最大权闭合子图)
- HDU5855 Less Time, More profit(最大权闭合子图)
- Less Time, More profit 最大权闭合子图(最大流最小割)
- hdu5855 Less Time, More profit 【最大流-最大权闭合子图】
- hdoj 5855 Less Time, More profit 【最大权闭合图】
- HDU 5855 Less Time, More profit
- hdu 3996 Gold Mine 最大权闭合子图
- HDU 5855 二分搜索+最大流
- 【HDU】3879 Base Station 最大权闭合子图