SGU 438 动态网络流,SGU挂了,我也不知道A没A
来源:互联网 发布:无锡服务器数据恢复 编辑:程序博客网 时间:2024/05/16 18:13
题目链接:https://cn.vjudge.net/contest/69431#problem/D
题意:
有一条河,河上有一些垃圾(看成点),人借助垃圾跳到对岸,已知垃圾坐标位置,人每次最大跳跃距离,河的
宽度以及人数,问是否所有人可以跳到对岸,若可以,求出最短时间。
解法:
第一次碰到动态流,还是队友推荐来做的。 题解来自:ORZ
我们知道时间的上限是n+m,因为对于第一个人他从一河岸跳到对岸最多踩m个垃圾,加上到达对岸的一步,
共需花m+1单位的时间,而第二个人他可以在第一人跳到第二个垃圾时重复第一人的跳法,也就是后面一人
比前面一人晚到对岸1个单位时间,那么有n-1人重复此过程,因此最大时间m+1+n-1=m+n,若超过此时
间,所有人未到对岸,显然是无解情况。
对于有解情况:我们先预处理所有垃圾两两之间的距离是否小于等于D,也就是能否在这些垃圾之间跳来跳
去,麻烦的是河岸并不是一个点,而是一条线,因此我们也要预处理能从左岸(出发地)跳到的垃圾(y坐标
<=D),和能从哪些垃圾跳到对岸(y坐标+D>=M).
然后根据时间拆点,记i点在t时刻的状态为(i,t),这里注意t=1,就是直接从左岸跳到对岸,这个可以判断
D>=M求得,然后我们从t=2开始枚举,这里要考虑清楚,我之前建模没想明白,t-1时刻,人是站在(i,t-
1)状态上的,那么t时刻人可以从(i,t-1)跳到对岸(如果满足条件的话),也就是要将所有(i,t-1)连
向汇点,千万不要将(i,t)连向汇点,当然也可以选择从(i,t-1)跳到(j,t)(i,j距离<=D),当然不要忘
了从左岸连向那些y坐标<=D的点(一步可达点),这样就差不多了。
最后别忘了,每个点需要拆成两个点,不这样做的话会有大量流量聚集在i点,然后通过下一时刻流出去,这
样就超过i在某一时刻最大人数限制了。此题拆点是挺麻烦的。
PS:这里最多会有10000割点左右,最坏情况有10^8条边,显然内存不允许,dinic算法也会TLE,所以可以推
断,数据显然不会出现这么多边和点的情况。所以随便开了2000000就AC。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int maxn = 15000;const int maxm = 2000000;const int inf = 0x3f3f3f3f;struct G{ int v, cap, next; G() {} G(int v, int cap, int next) : v(v), cap(cap), next(next) {}} E[maxm];int p[maxn], T;int d[maxn], temp_p[maxn], qw[maxn]; //d顶点到源点的距离标号,temp_p当前狐优化,qw队列void init(){ memset(p, -1, sizeof(p)); T = 0;}void add(int u, int v, int cap){ E[T] = G(v, cap, p[u]); p[u] = T++; E[T] = G(u, 0, p[v]); p[v] = T++;}bool bfs(int st, int en, int n){ int i, u, v, head, tail; for(i = 0; i <= n; i++) d[i] = -1; head = tail = 0; d[st] = 0; qw[tail] = st; while(head <= tail) { u = qw[head++]; for(i = p[u]; i + 1; i = E[i].next) { v = E[i].v; if(d[v] == -1 && E[i].cap > 0) { d[v] = d[u] + 1; qw[++tail] = v; } } } return (d[en] != -1);}int dfs(int u, int en, int f){ if(u == en || f == 0) return f; int flow = 0, temp; for(; temp_p[u] + 1; temp_p[u] = E[temp_p[u]].next) { G& e = E[temp_p[u]]; if(d[u] + 1 == d[e.v]) { temp = dfs(e.v, en, min(f, e.cap)); if(temp > 0) { e.cap -= temp; E[temp_p[u] ^ 1].cap += temp; flow += temp; f -= temp; if(f == 0) break; } } } return flow;}int dinic(int st, int en, int n){ int i, ans = 0; while(bfs(st, en, n)) { for(i = 0; i <= n; i++) temp_p[i] = p[i]; ans += dfs(st, en, inf); } return ans;}//最大流bool g[55][55];int n, m, val[55], xx[55], yy[55];int getid(int id, int t, int p){ return 2*n*(t-1)+p*n+id;}bool check(int t){ init(); int source = 0, sink = 2*n*t+1; for(int i=1; i<=n; i++){ for(int j=1; j<=t; j++){ add(getid(i,j,0),getid(i,j,1),val[i]); if(j<t){ add(getid(i,j,1),getid(i,j+1,0),inf); } } } for(int i=1; i<=n; i++){ if(g[0][i]){ for(int j=1; j<=t; j++) add(source, getid(i,j,0), inf); } if(g[i][n+1]){ for(int j=1; j<=t; j++) add(getid(i,j,1), sink, inf); } for(int j=1; j<=n; j++){ if(g[i][j]){ for(int k=1; k<t; k++){ add(getid(i,k,1), getid(j,k+1,0), inf); } } } } int ans = dinic(source, sink, sink+2); return ans >= m;}int main(){ while(scanf("%d%d", &n,&m) != EOF) { memset(g, 0, sizeof(g)); int d, w; scanf("%d%d", &d, &w); for(int i=1; i<=n; i++){ scanf("%d%d%d",&xx[i],&yy[i],&val[i]); } if(w<=d){ printf("1\n"); continue; } for(int i=1; i<=n; i++){ if(yy[i]<=d) g[0][i]=1; if(w-yy[i]<=d) g[i][n+1]=1; for(int j=1; j<=n; j++){ if(i!=j){ if(sqrt((xx[i]-xx[j])*(xx[i]-xx[j])+(yy[i]-yy[j])*(yy[i]-yy[j])) <= d){ g[i][j]=g[j][i]=1; } } } } int ans = -1, l=1, r=102; while(l <= r){ int mid = (l+r)/2; if(check(mid)) ans = mid, r = mid-1; else l = mid+1; } if(ans == -1) printf("IMPOSSIBLE\n"); else printf("%d\n", ans+1); } return 0;}
- SGU 438 动态网络流,SGU挂了,我也不知道A没A
- 动态网络流 SGU 438
- SGU 438 动态流
- [SGU]100. A+B
- SGU 100. A+B
- SGU a^b-b^a
- SGU 438 The Glorious Karlutka River =) 动态网络流
- sgu 151 Construct a triangle
- SGU 151 - Construct a triangle
- [SGU]112. a^b - b^a
- SGU 112. a^b-b^a 高精度
- SGU 112 a^b-b^a
- 【SGU】112. a^b - b^a 高精度
- SGU 112 a^b-b^a
- SGU 326 Perspective ( 网络流 )
- SGU 326 Perspective(网络流)
- sgu 438 The Glorious Karlutka River =) 网络流 动态流
- sgu 438 The Glorious Karlutka River =)(动态网络流)
- java多线程问题
- Abaqus简单部件受力分析
- 18. Hibernate_检索策略(lazy、fetch、batch-size等)
- 界面适配华为手机的虚拟按键的解决方案
- android 不同型号的终端的UI适配--一种解决方法
- SGU 438 动态网络流,SGU挂了,我也不知道A没A
- 网站性能体验34守则
- 参考了 网上 部分 代码 单链表
- iOS跳转微信朋友圈和扫一扫页面(已废弃)
- 一个简单的Makefile教程
- qrcode.js生成二维码
- 专利驳回的三大基本原因
- ORACLE PLSQL中文乱码解决,请留意细节
- Python中optparse模块使用学习