题目大意:

二维空间上有一些点,每个点有一个频率,圆心坐标,半径,设s点是频率最低的点,t是频率最高的点,要求从s点走到t点,在从点t回到点s。当从s走到t时,要求两个点表示的园相交并且第一个点的频率小于第二个点的频率,而从t到s,要第一个点的频率高于第二个点的频率,除了s点t点,所有的点走过一次就会消失,问是否存在这样的一种走法;

思路分析:从s到t频率降低,从t到s频率升高,其实也就是从s点走到t点能否有两条不同的路径;

代码实现:

Sap:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=310;
const int M=90010;
const int INF=0x3f3f3f3f;
int n,s,t,top,head[N],gap[N],cur[N],pre[N],dis[N];struct Edge{int to,next,flow;
}edge[M*2];struct Point{double fre;int x,y,r;
}point[N];int cmp(Point a,Point b){return a.fre<b.fre;
}int Check(int i,int j){return ((point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y))<(point[i].r+point[j].r)*(point[i].r+point[j].r);
}void Addedge(int from,int to,int flow){edge[top].to=to,edge[top].next=head[from],edge[top].flow=flow,head[from]=top++;edge[top].to=from,edge[top].next=head[to],edge[top].flow=0,head[to]=top++;
}void Bfs(){queue<int> q;memset(gap,0,sizeof(gap));memset(dis,-1,sizeof(dis));gap[0]=1,dis[t]=0;q.push(t);while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i+1;i=edge[i].next){if(dis[edge[i].to]==-1){dis[edge[i].to]=dis[u]+1;gap[dis[edge[i].to]]++;q.push(edge[i].to);}}}
}int Sap(){Bfs();memset(pre,-1,sizeof(pre));for(int i=0;i<n;++i) cur[i]=head[i];int u=s,cur_flow,max_flow=0,neck,tmp;while(dis[s]<=n){if(u==t){cur_flow=INF;for(int i=s;i!=t;i=edge[cur[i]].to){if(cur_flow>edge[cur[i]].flow){neck=i;cur_flow=edge[cur[i]].flow;}}for(int i=s;i!=t;i=edge[cur[i]].to){tmp=cur[i];edge[tmp].flow-=cur_flow;edge[tmp^1].flow+=cur_flow;}max_flow+=cur_flow;u=neck;}int i;for(i=cur[u];i+1;i=edge[i].next)if(edge[i].flow&&dis[u]==dis[edge[i].to]+1) break;if(i!=-1){cur[u]=i;pre[edge[i].to]=u;u=edge[i].to;}else{if(--gap[dis[u]]==0) break;cur[u]=head[u];int mindis=n;for(int i=head[u];i+1;i=edge[i].next)if(edge[i].flow&&mindis>dis[edge[i].to])mindis=dis[edge[i].to];dis[u]=mindis+1;gap[dis[u]]++;if(u!=s) u=pre[u];}}return max_flow;
}int main(){int T;scanf("%d",&T);while(T--){memset(head,-1,sizeof(head));top=0;scanf("%d",&n);s=0,t=n-1;for(int i=0;i<n;++i) scanf("%lf%d%d%d",&point[i].fre,&point[i].x,&point[i].y,&point[i].r);sort(point,point+n,cmp);if(Check(0,n-1)){printf("Game is VALID\n");continue;}for(int i=0;i<n;++i){for(int j=i+1;j<n;++j){if(Check(i,j)) Addedge(i,j,1);}}int res=Sap();if(res>=2) printf("Game is VALID\n");else printf("Game is NOT VALID\n");}
}

Dinic:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=310;
const int M=90010;
const int INF=0x3f3f3f3f;
int n,s,t,top,head[N],dis[N];
struct Edge{int to,next,flow;
}edge[M*2];struct Point{double fre;int x,y,r;
}point[N];int cmp(Point a,Point b){return a.fre<b.fre;
}int Check(int i,int j){return ((point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y))<(point[i].r+point[j].r)*(point[i].r+point[j].r);
}void Addedge(int from,int to,int flow){edge[top].to=to,edge[top].next=head[from],edge[top].flow=flow,head[from]=top++;edge[top].to=from,edge[top].next=head[to],edge[top].flow=0,head[to]=top++;
}int Bfs(){queue<int> q;memset(dis,-1,sizeof(dis));dis[s]=0;q.push(s);while(!q.empty()){int u=q.front();if(u==t) return 1;q.pop();for(int i=head[u];i+1;i=edge[i].next){if(dis[edge[i].to]==-1&&edge[i].flow){dis[edge[i].to]=dis[u]+1;q.push(edge[i].to);}}}return 0;
}int Dinic(int u,int sum){if(u==t) return sum;int max_flow=0;for(int i=head[u];i+1;i=edge[i].next){if(dis[edge[i].to]==dis[u]+1&&edge[i].flow){int a=Dinic(edge[i].to,Min(sum-max_flow,edge[i].flow));edge[i].flow-=a;edge[i^1].flow+=a;max_flow+=a;if(max_flow==sum) return max_flow;}}if(!max_flow) dis[u]=-1;return max_flow;
}int main(){int T;scanf("%d",&T);while(T--){memset(head,-1,sizeof(head));top=0;scanf("%d",&n);s=0,t=n-1;for(int i=0;i<n;++i) scanf("%lf%d%d%d",&point[i].fre,&point[i].x,&point[i].y,&point[i].r);sort(point,point+n,cmp);if(Check(0,n-1)){printf("Game is VALID\n");continue;}for(int i=0;i<n;++i){for(int j=i+1;j<n;++j){if(Check(i,j)) Addedge(i,j,1);}}int res=0;while(Bfs()){res+=Dinic(s,INF);}if(res>=2) printf("Game is VALID\n");else printf("Game is NOT VALID\n");}
}

HDU -- 4183 Pahom on Water(最大流)相关推荐

  1. hdu 4183 Pahom on Water 最大流

    一个平面上有n个圆, 每个圆都有一个频率, 有两个频率为400和789的圆, 问是否能从频率为400的圆走到频率为789的圆, 并从频率为789的圆走回频率为400的圆, 并且除了频率为400的圆, ...

  2. HDU 4183 Pahom on Water 来回走不重复点的网络流

    题目来源:HDU 4183 Pahom on Water 题意:若干个区域 每个区域有一个值 区域是圆 给出圆心和半径 从起点(值为400.0)到终点(值为789.0)满足走相交的圆 并且值必须递增 ...

  3. hdu 4183 Pahom on Water 网络流

    题意   二维空间上有一些点,每个点有一个半径r和频率f,要从某一个点S走到另一个点T,然后再从T回到S.从S到T时,如果两个点表示的圆相交并且第一个点小于第二个点的频率的,那么能从第一个点到第二个点 ...

  4. 【网络流】 HDU 4183 Pahom on Water 拆点

    题意:求两条路 能从 400.0 -> 789.0 且这两条路不想交(除了端点400,789 ) 求只能走一次的网络流需要用到拆点, 将点i  拆成 i 和 i+n  i->i+n的容量为 ...

  5. HDU 4183 Pahom on Water(点双连通分量)

    题意:有很多的被涂上颜色的呈圆形的垫子,一些垫子可以有相同的颜色,但是红色和紫罗兰只有一个,垫子摆放的时候可以相交,初始一个人站在红垫子上,这个人要从红垫子走到紫罗兰垫子,然后再从紫罗兰垫子走到红垫子 ...

  6. HDU 4183 Pahom on Wate【网络流+路径问题】

    HDU 4183 Pahom on Water: 题意: 有n(2≤n≤300)个点,每个点有个频率f(400.0≤f≤789.0)和二维坐标还有半径.如果点i能走到点j,那么以两个点为圆心半径分别为 ...

  7. 【HDOJ】4183 Pahom on Water

    就是一个网络流.red结点容量为2,查看最大流量是否大于等于2.对于条件2,把边反向加入建图.条件1,边正向加入建图. 1 /* 4183 */ 2 #include <iostream> ...

  8. HDU4183 Pahom on Water(最大流)

    题目好长好难懂0 0,直接翻了翻网上的题解. 大意是这样的:有n(2≤n≤300)n(2 \leq n\leq 300)个点,每个点有个频率f(400.0≤f≤789.0)f(400.0 \leq f ...

  9. 最大流 hdu 4183

    /** hdu 4183 求两点之间来回不重复的两条路就是要求从起点到终点至少有两条不重复的路径,最大流大于等于2即可 **/#include <iostream> #include &l ...

最新文章

  1. linux imq原理图,编译IMQ模块
  2. mysql基础拓扑图
  3. 计算机互联网行业高校,9家互联网巨头最青睐的重点大学汇总,网友:比各种排名强太多了...
  4. Flume 实战开发指南
  5. vue项目中iview表单验证 this.$refs[name].validate(valid = { }无效
  6. 《南溪的目标检测学习笔记》——PyTorch模型搭建模板
  7. virtualenv 安装及使用[转]
  8. C# 图片exif信息
  9. 下载文件变成php文档,关于文件下载后变成PHP格式的解决办法
  10. 3dmax报错信息大全,最全解决方案来了
  11. scrapy 官方文档(入门必备)
  12. python使用openpyxl插入excel批注,同时修改excel批注框大小
  13. Python基于OpenCV的土壤裂缝分割系统[源码&部署教程]
  14. Springboot 下载文件
  15. 修改Mac 共享Wifi默认的桥接IP
  16. 通证网:一建的报考条件
  17. 小程序--广州旅游推荐
  18. View/ViewGroup的生命周期
  19. Linux:《gzip》《bzip2》压缩解压
  20. 手把手教你Linux虚拟机安装(超详细)

热门文章

  1. 手机APP对接支付功能总结
  2. 史上最全Eclipse快捷键,学会了开发效率翻倍
  3. Word转PDF转换器怎么转换
  4. mysql 左对齐_CSS:左对齐标签,右对齐(CSS : Align label left, text right)
  5. Word 2010如何从正文开始设置页码
  6. 读取xml到DataSet中去
  7. 信号与系统课件和笔记
  8. Win10 只有Edge无法上网的解决方法
  9. Java与C、C++的10大区别-总结
  10. 华为云服务器可用区是什么意思?