POJ1149_PIGS_网络流
来源:互联网 发布:增值税发票数据导出 编辑:程序博客网 时间:2024/06/16 20:08
#include <iostream>#include <string.h>#include <cstdio>#include <vector>#include <queue>#define INF 0x3f3f3f3f#define MAXM 1010#define MAXN 110using namespace std;int cap[MAXM];struct Edge{ Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {} int from, to, cap, flow;};struct Dinic{ int n,m,s,t; //结点数,边数(包括反向弧),源点与汇点编号 vector<Edge> edges; //边表 edges[e]和edges[e^1]互为反向弧 vector<int> G[MAXN]; //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[MAXN]; //BFS使用,标记一个节点是否被遍历过 int d[MAXN]; //从起点到i点的距离 int cur[MAXN]; //当前弧下标 void init(int n,int s,int t) { this->n = n, this->s = s,this->t = t; for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q;//用来保存节点编号的 Q.push(s); d[s] = 0; vis[s] = true; while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(!vis[e.to] && e.cap > e.flow) { vis[e.to] = true; d[e.to] = d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if(x == t || a == 0) return a; int flow = 0, f;//flow用来记录从x到t的最小残量 for(int& i = cur[x]; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(d[x] + 1 == d[e.to] && (f = DFS(e.to,min(a,e.cap-e.flow))) > 0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow; } int Maxflow() { int flow = 0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; }} DC;int book[MAXM], book1[MAXN];int main(){ //freopen("aa.txt", "r", stdin); int m, n, a, b; memset(book, 0, sizeof(book)); memset(book1, 0, sizeof(book1)); DC.init(MAXN, 0, MAXN - 1); scanf("%d %d", &m, &n); for (int i = 1; i <= m; i++) scanf("%d", &cap[i]); int key; for (int i = 1; i <= n; i++) //n customer m house { cin >> a; while (a--) { cin >> key; if (!book[key]) { if (!book1[i]) { DC.AddEdge(0, i, cap[key]); book1[i] = DC.edges.size() - 2; } else DC.edges[book1[i]].cap += cap[key]; book[key] = i; } else DC.AddEdge(book[key], i, INF); } cin >> b; DC.AddEdge(i, MAXN - 1, b); } cout << DC.Maxflow() << endl;}
题目大意
若干个顾客依次来到猪圈,各自有若干个猪圈的钥匙,各自有做多买猪量,每个猪圈有若干头猪,每个顾客到达并打开他有钥匙的猪圈买走猪后,能交将剩下的猪在打开的猪圈中人以分配。问最多能卖出多少猪。
思路
建立超级源点和超级汇点,顾客和源点的边权值为他拥有钥匙的猪圈的猪总数,和汇点的边权值为他最多能购买的猪的数量。顾客之间能建立一种关系:a顾客先于顾客b到达某猪圈,则a和b之间可以建立一条容量为无穷大的边。跑一遍网络流。
阅读全文
0 0
- POJ1149_PIGS_网络流
- 【网络流】网络扩容
- 网络流
- 网络流
- 网络流
- 网络流
- 网络流
- 网络流
- 网络流
- 【网络流】
- 【网络流】
- 网络流
- 网络流
- 网络流
- 网络流
- 网络流
- 网络流
- 网络流
- c++实验六
- Integer to Roman【LeetCode】
- verilog 新手导航
- java-一维二维数组的定义、使用二维数组、遍历数组
- 区块链搭建以及智能合约的运行
- POJ1149_PIGS_网络流
- 程序员所具备的素质[转]
- 你要工作多久,才能赚够一份早餐钱?
- FileWriter无法指定文件输出编码
- 详解Google Code Prettify代码高亮Prettify.js库使用及其应用
- jQuery获取Select选中的Text和Value,根据Value值动态添加属性等
- 判断服务端是否支持跨域请求
- 第八届蓝桥杯【省赛试题4】方格分割
- 装双系统时装在了逻辑分区的解决方案