poj 3281 Dining (网络流)
2015-08-18 15:08
579 查看
思路:
因为需要同时给一头牛分配所喜欢的食物和饮料,所以我们需要把食物和饮料对应的两个匹配通过下面的方法联合起来进行求解。
把食物对应的牛和饮料对应的牛拆成两个顶点,之间连一条流量为1的边,就保证的一头牛不会被分配多组食物和饮料。
图的顶点中除了食物和牛,牛和饮料之外还应该有一个源点s和一个汇点t
在s和所有食物,t和所有饮料之间连一条边
边的方向为s -> 食物 -> 牛 -> 牛 -> 饮料 -> t
之后就是普通的网络流了
约束:
1<= N <= 100
1<= F <= 100
1<= D <= 100
因为需要同时给一头牛分配所喜欢的食物和饮料,所以我们需要把食物和饮料对应的两个匹配通过下面的方法联合起来进行求解。
把食物对应的牛和饮料对应的牛拆成两个顶点,之间连一条流量为1的边,就保证的一头牛不会被分配多组食物和饮料。
图的顶点中除了食物和牛,牛和饮料之外还应该有一个源点s和一个汇点t
在s和所有食物,t和所有饮料之间连一条边
边的方向为s -> 食物 -> 牛 -> 牛 -> 饮料 -> t
之后就是普通的网络流了
约束:
1<= N <= 100
1<= F <= 100
1<= D <= 100
/*********************************************** * Author: fisty * Created Time: 2015-08-17 11:09:40 * File Name : poj3281.cpp *********************************************** */ #include <iostream> #include <cstring> #include <deque> #include <cmath> #include <queue> #include <stack> #include <list> #include <map> #include <set> #include <string> #include <vector> #include <cstdio> #include <bitset> #include <algorithm> using namespace std; #define Debug(x) cout << #x << " " << x <<endl #define Memset(x, a) memset(x, a, sizeof(x)) const int INF = 0x3f3f3f3f; typedef long long LL; typedef pair<int, int> P; #define FOR(i, a, b) for(int i = a;i < b; i++) #define lson l, m, k<<1 #define rson m+1, r, k<<1|1 #define MAX_N 410 int N, F, D; bool likeF[MAX_N][MAX_N]; //食物的喜好 bool likeD[MAX_N][MAX_N]; //饮料的喜好 struct edge{ int to,cap, rev; }; vector<edge> G[MAX_N]; int level[MAX_N]; int iter[MAX_N]; void add_edge(int from, int to, int cap){ G[from].push_back((edge){to, cap, G[to].size()}); G[to].push_back((edge){from, 0, G[from].size()-1}); } void bfs(int s){ memset(level, -1, sizeof(level)); queue<int> que; level[s] = 0; que.push(s); while(!que.empty()){ int v = que.front(); que.pop(); for(int i = 0;i < G[v].size(); i++){ edge &e = G[v][i]; if(e.cap > 0 && level[e.to] < 0){ level[e.to] = level[v] + 1; que.push(e.to); } } } } int dfs(int v, int t, int f){ if(v == t) return f; for(int &i = iter[v];i < G[v].size(); i++){ edge &e = G[v][i]; if(e.cap > 0 && level[v] < level[e.to]){ int d = dfs(e.to, t, min(f, e.cap)); if(d > 0){ e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } int max_flow(int s, int t){ int flow = 0; for(;;){ bfs(s); if(level[t] < 0) return flow; memset(iter, 0, sizeof(iter)); int f; while((f = dfs(s, t, INF)) > 0){ flow += f; } } } void solve(){ //0 ~ N-1 食物一侧的牛 //N ~ 2*N-1 饮料一侧的牛 //2*N ~ 2*N + F -1 食物 //2*N+F ~ 2*N + F + D -1 饮料 int s = N * 2 + F + D; int t = s + 1; for(int i = 0;i < F; i++){ add_edge(s, N * 2 + i, 1); } for(int i = 0;i < D; i++){ add_edge(N * 2 + F + i, t , 1); } for(int i = 0;i < N; i++){ add_edge(i, N + i, 1); for(int j = 0;j < F; j++){ if(likeF[i][j]){ add_edge(N * 2 + j, i, 1); } } for(int j = 0;j < D; j++){ if(likeD[i][j]){ add_edge(N + i, N * 2 + F + j, 1); } } } printf("%d\n", max_flow(s, t)); } int main() { //freopen("in.cpp", "r", stdin); //cin.tie(0); //ios::sync_with_stdio(false); scanf("%d%d%d", &N, &F, &D); Memset(likeF, false); Memset(likeD, false); for(int i = 0;i < N; i++){ int f, d; int x; scanf("%d%d", &f, &d); for(int j = 0;j < f; j++){ scanf("%d", &x); likeF[i][x-1] = true; } for(int j = 0;j < d; j++){ scanf("%d", &x); likeD[i][x-1] = true; } } solve(); return 0; }
相关文章推荐
- Java——网络编程
- hdu 4278 2012天津赛区网络赛 数学 *
- VMware11 + centOs 7 安装及网络配置
- linux tcpdump命令详解
- 曾经的笔记迁移__通用链表网络版
- http响应码信息
- 打造安全的App!iOS安全系列之 HTTPS
- 【计算机网络】HTTP协议详解
- http://www.cocoachina.com/ios/20150812/12938.html
- java - (06) http
- http://www.cnblogs.com/kissazi2/p/4133927.html
- Android安卓根据地址下载文件并保存到本地(HttpDownload)
- Android 快速开发框架网络篇-Android-Async-Http
- HTTP 协议详解
- 国家自然科学基金重点项目启动暨软件定义网络 技术前瞻研讨会
- iOS应用架构谈 网络层设计方案
- HTTP 状态消息、code状态码查询
- 《从零开始学Swift》学习笔记http(Day1)——我的第一行Swift代码
- 数据中心网络虚拟化-隧道技术
- 基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类