博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[CEOI2008]order
阅读量:5173 次
发布时间:2019-06-13

本文共 3013 字,大约阅读时间需要 10 分钟。

 

最小割。

不过割掉边代表付出某一种代价,而题中让求的是利润。所以我们先把完成所有任务的总利润加起来,然后算没有完成任务付出的代价。

建图比较明白:

1.源点向任务连一条边,容量为完成这个任务赚到的钱。割掉代表这个任务没完成。

2.每一个机器向汇点连一条边,容量为买这个机器所花的钱。割掉代表没买这个机器。

3.每一个任务向完成这个任务要用到的机器连边,容量为租用该机器所花的钱。

图大概是这样的:

比如完成这一个任务需要三个机器。

我们考虑最小割有哪几种情况:

1.x < min(a, d) + min(b, e) + min(c, f)。那么割掉(x)边,就是说完成这个任务得到的钱太少了,亏本,那就放弃算了。

2.对于每一个机器,x >= min(a, d) + min(b, e) + min(c, f)。说明完成这个任务能赚点钱,那就完成吧。

代码:

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 2.5e3 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 int n, m, t; 38 int sum = 0; 39 40 struct Edge 41 { 42 int from, to, cap, flow; 43 }; 44 vector
edges; 45 vector
G[maxn]; 46 void addEdge(int from, int to, int w) 47 { 48 edges.push_back((Edge){ from, to, w, 0}); 49 edges.push_back((Edge){to, from, 0, 0}); 50 int sz = edges.size(); 51 G[from].push_back(sz - 2); 52 G[to].push_back(sz - 1); 53 } 54 55 int dis[maxn]; 56 bool bfs() 57 { 58 Mem(dis, 0); dis[0] = 1; 59 queue
q; q.push(0); 60 while(!q.empty()) 61 { 62 int now = q.front(); q.pop(); 63 for(int i = 0; i < (int)G[now].size(); ++i) 64 { 65 Edge& e = edges[G[now][i]]; 66 if(!dis[e.to] && e.cap > e.flow) 67 { 68 dis[e.to] = dis[now] + 1; 69 q.push(e.to); 70 } 71 } 72 } 73 return dis[t]; 74 } 75 int cur[maxn]; 76 int dfs(int now, int res) 77 { 78 if(now == t || res == 0) return res; 79 int flow = 0, f; 80 for(int& i = cur[now]; i < (int)G[now].size(); ++i) 81 { 82 Edge& e = edges[G[now][i]]; 83 if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(res, e.cap - e.flow))) > 0) 84 { 85 e.flow += f; 86 edges[G[now][i] ^ 1].flow -= f; 87 flow += f; res -= f; 88 if(res == 0) break; 89 } 90 } 91 return flow; 92 } 93 94 int minCut() 95 { 96 int flow = 0; 97 while(bfs()) 98 { 99 Mem(cur, 0);100 flow += dfs(0, INF);101 }102 return flow;103 }104 105 int main()106 {107 n = read(); m = read();108 t = n + m + 1;109 for(int i = 1; i <= n; ++i)110 {111 int x = read(), d = read();112 sum += x; addEdge(0, i, x);113 for(int j = 1; j <= d; ++j)114 {115 int y = read(), w = read();116 addEdge(i, n + y, w);117 }118 }119 for(int i = 1; i <= m; ++i) 120 {121 int w = read();122 addEdge(n + i, t, w);123 }124 write(sum - minCut()); enter;125 return 0;126 }
View Code

 

转载于:https://www.cnblogs.com/mrclr/p/9696871.html

你可能感兴趣的文章
单片机编程
查看>>
Filter in Servlet
查看>>
Linux--SquashFS
查看>>
Application Pool Identities
查看>>
2017-3-24 开通博客园
查看>>
【MySQL性能优化】MySQL常见SQL错误用法
查看>>
Vue2全家桶之一:vue-cli(vue脚手架)超详细教程
查看>>
Struts 2 常用技术
查看>>
树形DP
查看>>
python flask解决上传下载的问题
查看>>
语法测试
查看>>
CES1
查看>>
java webcontroller访问时报415错误
查看>>
qcow2、raw、vmdk等镜像格式
查看>>
Jzoj5455【NOIP2017提高A组冲刺11.6】拆网线
查看>>
特定字符序列的判断(1028)
查看>>
华为面试
查看>>
平衡二叉树(AVL Tree)
查看>>
【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治
查看>>
【CF799E】Aquarium decoration 线段树
查看>>