HDU 4183 网络流
2016-04-24 20:31
260 查看
#include<cstdio> #include<queue> #include<cstring> #include<iostream> #include<algorithm> #define debu using namespace std; const int maxn = 5000+10; const int INF = 1000000000; struct Edge { int from, to, cap, flow; Edge(int a,int b,int c,int d):from(a),to(b),cap(c),flow(d) {} }; 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)); int 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; } }; struct point { double h; int x,y,r; }; Dinic g; int t,n; point a[maxn]; int check(point a,point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)<=(a.r+b.r)*(a.r+b.r); } int main() { #ifdef debug freopen("in.in","r",stdin); #endif // debug scanf("%d",&t); while(t--) { point s,t; scanf("%d",&n); g.init(2*n+50); for(int i=1; i<=n; i++) { scanf("%lf%d%d%d",&a[i].h,&a[i].x,&a[i].y,&a[i].r); if(a[i].h==789.0) s=a[i]; if(a[i].h==400.0) t=a[i]; } if(check(s,t)) { printf("Game is VALID\n"); continue; } for(int i=1; i<=n; i++) { g.addedge(i,i+n,1); if(a[i].h!=789.0&&check(a[i],s)) g.addedge(0,i,1); if(a[i].h!=400.0&&check(a[i],t)) g.addedge(i+n,2*n+5,1); for(int j=1; j<=n; j++) if(i!=j&&check(a[i],a[j])) { if(a[i].h>a[j].h) g.addedge(i+n,j,1); else g.addedge(j+n,i,1); } } int ans=g.Maxflow(0,2*n+5); if(ans<2) printf("Game is NOT VALID\n"); else printf("Game is VALID\n"); } return 0; }
图上有N个圆形的光谱,一个人想从红色圆谱到紫罗兰圆谱,再由紫罗兰光谱返回红色光谱。图中可能需要经过其它的圆形光谱,现在给出如下限制:
1,红色光谱和紫罗兰光谱允许走两次,其它的光谱若走过一次不能再走。
2,对于任意的光谱A和光谱B,只要两个光谱相交,就可以从光谱频率大的圆经过光谱频率小的圆。
问你这个人能不能实现这个过程。
思路:建立超级源点0,超级汇点N + 1.
一:源点连接紫罗兰光谱,边权为2。
二:红色光谱连接汇点,边权为2。
三:对于任意相交的两个光谱,从频率大的引一条到频率小的边,边权为1。
最后从超级源 到 超级汇 跑一下最大流,看Maxflow 是否为2。若为2就说明可以实现,否则不能实现。
相关文章推荐
- Servlet课程0424(三) 通过继承HttpServlet来开发Servlet
- TCP/IP backlog
- VirtualBox中centos网络配置
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛
- IPerf——网络测试工具介绍与源码解析(2)
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛 乘电梯
- Android开发本地及网络Mp3音乐播放器(六)实现独立音乐播放界面
- Android开发本地及网络Mp3音乐播放器(六)实现独立音乐播放界面
- [网络流24题]T1 飞行员配对方案问题
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛 . candy
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛 G. 易彰彪的一张表
- TCP/IP-初识
- OKHttp使用总结
- IOS网络通信 socket第三方库 AsyncSocket(GCDAsyncSocket)
- Android常用抓包工具之TcpDump
- 网络爬虫(网络蜘蛛)之网页抓取
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛 A题 换瓶盖
- 【转载】Gradle学习 第十章:网络应用快速入门
- Laxcus大数据管理系统2.0(8)- 第六章 网络通信
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛