hunnu OJ 11567 Escaping(拆点型最大匹配/网络流)
来源:互联网 发布:oracle数据库基本语句 编辑:程序博客网 时间:2024/06/06 23:48
题意:
l悟空号将会在t秒以后沉入海底,那时船上所有的人将会死亡(包括t秒时也不能生存)。但是,在某些房间中会有一些救生设备(不一定只有一个),人可以花费1分钟的时间走到相邻的另外四个房间。如果船上的人获得这些救生设备那么他们将会存活下来,请找出最大能存活的人数.
思路:建立源点跟汇点,将存在需要救援的房间与源点相连,容量为该房间的人数。将存在救生设备的房间与汇点相连,容量为救生设备的数目。中间点则考虑在t分钟内是否能够到达进行连边即可。
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<iostream>using namespace std;const int maxn = 10000 + 50;const int INF = 1e9;struct Edge { int from, to, cap, flow;};struct Dinic { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void init(int n) { this->n = n; 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); vis[s] = 1; d[s] = 0; 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] = 1; 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; 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 s, int t) { this->s = s; this->t = t; int flow = 0; while(BFS()) { memset(cur, 0, sizeof cur ); flow += DFS(s, INF); } return flow; }};Dinic solve;int mtx[50][50];int dist(int x1, int y1, int x2, int y2){ return abs(x1-x2) + abs(y1-y2);}int main(){#ifdef LOCAL_DEFINE freopen("in.cpp", "r", stdin); freopen("out.cpp", "w", stdout);#endif // LOCAL_DEFINE int n, tt, x; int s, t; while(~scanf("%d%d", &n, &tt)) { int lmt = n*n; s = lmt*2 + 1; t = lmt*2 + 2; solve.init(t+2); for(int i=0; i<n; ++i) { for(int j=0; j<n; ++j) { scanf("%d", &mtx[i][j]); if(mtx[i][j]>0) { solve.AddEdge( s, n*i+j, mtx[i][j]); } } } for(int i=0; i<n; i++) for(int j=0; j<n; j++) { scanf("%d",&x); if(x>0) { int u = n*i+j + lmt; solve.AddEdge(u, t, x); for(int i1=0; i1<n; ++i1) for(int j1=0; j1<n; ++j1) if(mtx[i1][j1]>0 && dist(i1, j1, i, j)<=tt){ int v = n*i1 + j1; solve.AddEdge(v, u, INF); } } } int ans = solve.MaxFlow(s, t); printf("%d\n", ans); } return 0;}
1 0
- hunnu OJ 11567 Escaping(拆点型最大匹配/网络流)
- HUNNU 11567 Escaping(最大流)
- HUNAN OJ 11567 Escaping
- hunnu OJ 11564 Easy Delete(二维坐标的离散化处理+最大匹配)
- 【哈理工OJ 750题纪念!】Hrbust 2200 Escaping【建图+最大流-------Dinic】
- 【HrbustOJ】Escaping(网络流,二部图)
- 福州oj--2232--炉石传说(最大匹配||最大流)
- POJ 1274 网络流最大匹配
- 【网络流-二分图最大匹配】poj3041Asteroids
- POJ 3281 Dining 匹配,网络最大流
- 网络最大流、二分图最大匹配、POJ2536
- 二分图最大匹配和网络最大流的转换
- Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)
- [二分图匹配] hunnu 10689 Antenna Placement
- POJ3041 二分图最大匹配(网络流算法)
- 网络最大流与二分匹配之间的关系
- hdu5249 Tricks Device(网络流最大匹配)
- 网络流24题之五 圆桌问题 最大匹配
- retain
- 记真实自己,炫精彩人生---《爱记》app使用体验
- Mac下使用Android Studio 获取 SHA1和MD5
- struts2的工作流程
- java 代理模式
- hunnu OJ 11567 Escaping(拆点型最大匹配/网络流)
- 【细说PHP学习】第十一章 字符串处理
- Spring监听器与proxool.xml(数据库连接池)
- Android典型界面设计(5)——使用SlidingMenu和DrawerLayout分别实现左右侧边栏
- IDW插值服务
- poj 2796
- objective-C中没有"接口"与"泛型"这样的说法,但有正式协议protocal 和 一种特殊的指针id类型
- Solr Cache使用介绍及分析
- 利用 gnuplot 绘制时间序列图 http://blog.csdn.net/liyuanbhu/article/details/8497582