传送门:HDU 5855

题意:

有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;elsel = 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 最大权闭合子图 + 二分相关推荐

  1. hdu 3917 Road constructions 最大权闭合子图

    样例说明: n(城市数目)   m(工程队数目) 每个工程队上交的税收 val[i] k(k个工程) xi   yi  ci  costi , 工程队ci承包由xi到yi,政府的补贴为costi 注意 ...

  2. 最大权闭合子图(poj 2987 Firing)

    Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 10884   Accepted: 3286 Descript ...

  3. 2018.06.27Firing(最大权闭合子图)

    Firing Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 11558 Accepted: 3494 Description ...

  4. poj 2987 Firing (最大权闭合子图)

    Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 10248   Accepted: 3110 Descript ...

  5. 最大权闭合子图(RMRC2017 Open-Pit Mining)

    闭合图:对于一个有向图G,存在点集合V,任取点u属于V,u的出边的另一个点也属于V,则为闭合图. 理解:任取一起点,终点必定是无出度的点. 最大权闭合子图:当每个点有一个权值w(有正有负),点权和最大 ...

  6. poj 2987 Firing【最大权闭合子图+玄学计数 || BFS】

    玄学计数 LYY Orz 第一次见这种神奇的计数方式,乍一看非常不靠谱但是仔细想想还卡不掉 就是把在建图的时候把正权变成w*10000-1,负权变成w*10000+1,跑最大权闭合子图.后面的1作用是 ...

  7. 最大权闭合子图(最小割)

    最大权闭合子图(最大流最小割) •参考资料 [1]最大权闭合子图 •权闭合子图 存在一个图的子图,使得子图中的所有点出度指向的点依旧在这个子图内,则此子图是闭合子图. 在这个图中有8个闭合子图:∅,{ ...

  8. 【转载】最大权闭合子图 【网络流】

    原文链接 定义 所谓闭合子图就是给定一个有向图,从中选择一些点组成一个点集V.对于V中任意一个点,其后续节点都仍然在V中. 建模 首先建立源点s和汇点t,将源点s与所有权值为正的点相连,容量为权值:将 ...

  9. Cogs 727. [网络流24题] 太空飞行计划(最大权闭合子图)

    [网络流24题] 太空飞行计划 ★★☆ 输入文件:shuttle.in 输出文件:shuttle.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] W 教授正在为国家航天中心计 ...

  10. #1398 : 网络流五·最大权闭合子图

    题目链接 结论 最大权闭合子图的权值 === 所有正权点之和−-−最小割 简单割(或最小割)将有向图分成两类,与源点sss相连的称为SSS,与汇点ttt相连的称为TTT 割的流量===与sss相连的正 ...

最新文章

  1. MobileNet Unet
  2. 设计模式:单例模式之懒汉式
  3. python安装pymssql
  4. Ansible-list-Dictionary-数据格式
  5. java如何爬取304_HTTP 304错误的详细讲解
  6. spring boot+mybatis整合
  7. java第一次上机_java第一次上机实验--验证码
  8. Python自动化开发学习的第九周----线程、进程、协程
  9. colordialog通过哪属性取其颜色_IT兄弟连 HTML5教程 CSS3揭秘 CSS常见的样式属性和值1...
  10. Linux Tun/Tap网口(/dev/net/tun)的读写方法
  11. 判断数据类型的几种办法
  12. 对于集成SP3后后不能激活的解释
  13. 使用JavaParser进行java源码解析
  14. ANSYS网格转化为模型、ANSYS网格导入到workbench分析
  15. c语言人机大战五子棋,五子棋人机大战将打响 祁观将与AI弈心五番棋对决
  16. 代理的原理及类型总结
  17. 對Googgle adsense廣告作弊和Googeladsense點擊廣告的生存前景看法
  18. 微软所有正版软件下载网站ITELLYOU
  19. 网易云音乐修改名字怎么老是服务器错误,网易云音乐为什么改了名字?网抑云是怎么回事...
  20. 暗影精灵电脑 开机速度慢的解决方法

热门文章

  1. e路航 LH900N地图升级
  2. oracle 范鑫_【企业信息化研究所】TF—SWUFE Oracle Club招新宣讲,只为和你相遇
  3. 我的世界java出生蘑菇岛,我的世界:有出生蘑菇岛和要塞的超大村庄?这超富有种子满足你!...
  4. 选择信号的采样频率和信号长度的技巧
  5. 用Python画一个精确的中国地图(数据+代码10行)
  6. C 实现黑客帝国数字雨
  7. 制作简单的个人Logo
  8. linux中双方同步unison服务器搭建
  9. 程序员健身了6个月,瘦了 30 斤,怎么做到的?
  10. R语言:lengths计算列表list中元素的个数