Pahom on Water

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 629    Accepted Submission(s): 288

Problem Description
Pahom on Water is an interactive computer game inspired by a short story of Leo Tolstoy about a poor man who, in his lust for land, forfeits everything. The game's starting screen displays a number of circular pads painted with colours
from the visible light spectrum. More than one pad may be painted with the same colour (defined by a certain frequency) except for the two colours red and violet. The display contains only one red pad (the lowest frequency of 400 THz) and one violet pad (the
highest frequency of 789 THz). A pad may intersect, or even contain another pad with a different colour but never merely touch its boundary. The display also shows a figure representing Pahom standing on the red pad.

The game's objective is to walk the figure of Pahom from the red pad to the violet pad and return back to the red pad. The walk must observe the following rules:

1.If pad α and pad β have a common intersection and the frequency of the colour of pad α is strictly smaller than the frequency of the colour of pad β, then Pahom figure can walk from α to β during the walk from the red pad to the violet pad

2. If pad α and pad β have a common intersection and the frequency of the colour of pad α is strictly greater than the frequency of the colour of pad β, then Pahom figure can walk from α to β during the walk from the violet pad to the red pad

3. A coloured pad, with the exception of the red pad, disappears from display when the Pahom figure walks away from it.

The developer of the game has programmed all the whizzbang features of the game. All that is left is to ensure that Pahom has a chance to succeed in each instance of the game (that is, there is at least one valid walk from the red pad to the violet pad and
then back again to the red pad.) Your task is to write a program to check whether at least one valid path exists in each instance of the game.
 
Input
The input starts with an integer K (1 <= K <= 50) indicating the number of scenarios on a line by itself. The description for each scenario starts with an integer N (2 <= N <= 300) indicating the number of pads, on a line by itself,
followed by N lines that describe the colors, locations and sizes of the N pads. Each line contains the frequency, followed by the x- and y-coordinates of the pad's center and then the radius. The frequency is given as a real value with no more than three
decimal places. The coordinates and radius are given, in meters, as integers. All values are separated by a single space. All integer values are in the range of -10,000 to 10,000 inclusive. In each scenario, all frequencies are in the range of 400.0 to 789.0
inclusive. Exactly one pad will have a frequency of “400.0” and exactly one pad will have a frequency of “789.0”.
 
Output
The output for each scenario consists of a single line that contains: Game is VALID, or Game is NOT VALID
 
Sample Input
2
2
400.0 0 0 4
789.0 7 0 2
4
400.0 0 0 4
789.0 7 0 2
500.35 5 0 2
500.32 5 0 3
 
Sample Output
Game is NOT VALID
Game is VALID
 
Source
 

题意:就是给出n个pad(衬垫)接下来每一行代表一个pad,每一个pad有一个颜色频率 f ,圆心坐标(x,y)和半径r. 如今从颜色频率f==400的 pad 開始走到 f==789.0的pad,这样走的规则是两圆有交点且f[u]<f[v]说明能够从u-->v。再从f==789.0走到f==400。走的规则是两圆有交点且f[u]>f[v]表明能够从u-->v。

问有没有这种一条路从起点走出后回到起点。(不能经过同一条边)

解题:由于从起点s走到终点t再回到s,不能经过同一条边。事实上就是找两条从s-->t的路。经过的边不能同样,就能够满足要求。建图:衬垫 u,衬垫  v  ,假设 f[u]<f[v]且两圆有交点。则建一条边,边容为1。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
#define captype int const int MAXN = 100010; //点的总数
const int MAXM = 400010; //边的总数
const int INF = 1<<30;
struct EDG{
int to,next;
captype cap,flow;
} edg[MAXM];
int eid,head[MAXN];
int gap[MAXN]; //每种距离(或可觉得是高度)点的个数
int dis[MAXN]; //每一个点到终点eNode 的最短距离
int cur[MAXN]; //cur[u] 表示从u点出发可流经 cur[u] 号边
int pre[MAXN]; void init(){
eid=0;
memset(head,-1,sizeof(head));
}
//有向边 三个參数。无向边4个參数
void addEdg(int u,int v,captype c,captype rc=0){
edg[eid].to=v; edg[eid].next=head[u];
edg[eid].cap=c; edg[eid].flow=0; head[u]=eid++; edg[eid].to=u; edg[eid].next=head[v];
edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++;
}
captype maxFlow_sap(int sNode,int eNode, int n){//n是包含源点和汇点的总点个数,这个一定要注意
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
pre[sNode] = -1;
gap[0]=n;
captype ans=0; //最大流
int u=sNode;
while(dis[sNode]<n){ //推断从sNode点有没有流向下一个相邻的点
if(u==eNode){ //找到一条可增流的路
captype Min=INF ;
int inser;
for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]) //从这条可增流的路找到最多可增的流量Min
if(Min>edg[i].cap-edg[i].flow){
Min=edg[i].cap-edg[i].flow;
inser=i;
}
for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]){
edg[i].flow+=Min;
edg[i^1].flow-=Min; //可回流的边的流量
}
ans+=Min;
u=edg[inser^1].to;
continue;
}
bool flag = false; //推断是否能从u点出发可往相邻点流
int v;
for(int i=cur[u]; i!=-1; i=edg[i].next){
v=edg[i].to;
if(edg[i].cap-edg[i].flow>0 && dis[u]==dis[v]+1){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
//假设上面没有找到一个可流的相邻点,则改变出发点u的距离(也可觉得是高度)为相邻可流点的最小距离+1
int Mind= n;
for(int i=head[u]; i!=-1; i=edg[i].next)
if(edg[i].cap-edg[i].flow>0 && Mind>dis[edg[i].to]){
Mind=dis[edg[i].to];
cur[u]=i;
}
gap[dis[u]]--;
if(gap[dis[u]]==0) return ans; //当dis[u]这样的距离的点没有了,也就不可能从源点出发找到一条增广流路径
//由于汇点到当前点的距离仅仅有一种。那么从源点到汇点必定经过当前点,然而当前点又没能找到可流向的点,那么必定断流
dis[u]=Mind+1;//假设找到一个可流的相邻点,则距离为相邻点距离+1。假设找不到,则为n+1
gap[dis[u]]++;
if(u!=sNode) u=edg[pre[u]^1].to; //退一条边
}
return ans;
}
struct node{
double f,x,y,r;
}a[305];
double ABS(double rr){
return rr>0? rr:-rr;
}
bool judge(int i,int j){
if(a[i].f>=a[j].f)
return 0;
double d=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y));
if(a[i].r+a[j].r<d||d<ABS(a[i].r-a[j].r))
return 0;
return 1;
}
int main(){
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
int s , t;
for(int i=1; i<=n; i++){
scanf("%lf%lf%lf%lf",&a[i].f,&a[i].x,&a[i].y,&a[i].r);
if(a[i].f==400.0)
s=i;
else if(a[i].f==789.0)
t=i;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(i!=j&&judge(i,j))
addEdg(i,j,1);
int ans = maxFlow_sap(s,t,n);
if(ans>1)
printf("Game is VALID\n");
else
printf("Game is NOT VALID\n");
}
}

HDU 4183 Pahom on Water(最大流SAP)的更多相关文章

  1. HDU 4183 Pahom on Water(最大流)

    https://vjudge.net/problem/HDU-4183 题意: 这道题目的英文实在是很难理解啊. 给出n个圆,每个圆有频率,x.y轴和半径r4个属性,每次将频率为400的圆作为起点,频 ...

  2. hdoj 4183 Pahom on Water

    Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. Pahom on Water(最大流)

    Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. M - Escape - HDU 3605 - (缩点+最大流SAP)

    题目大意:2012世界末日来了,科学家发现了一些星球可以转移人口,不过有的人可以在一些星球上生存有的人不行,而且每个星球都有一定的承载量,现在想知道是否所有的人都可以安全转移呢? 输入:首先输入一个N ...

  5. 【HDOJ】4183 Pahom on Water

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

  6. hdu 4183 EK最大流算法

    欢迎参加——每周六晚的BestCoder(有米!) Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327 ...

  7. hdu 4183(网络流)

    Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. HDU 3549 Flow Problem(最大流)

    HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...

  9. HDU 4974 A simple water problem(贪心)

    HDU 4974 A simple water problem pid=4974" target="_blank" style="">题目链接 ...

随机推荐

  1. 用python语言写一个简单的计算器

    假如我们有这样一个式子: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2 ...

  2. excel另存为csv

    # -*- coding: utf-8 -*- """ Created on Tue Jul 11 21:25:57 2017 import pandas as pd i ...

  3. 兼容浏览器 div固定浏览器窗口底部 浮动div

    css内容: <style type="text/css"> #ken_BB { padding-right:30px; text-align: center; col ...

  4. MVC系列学习(十三)-合并JS和CSS

    1.先来看看,不用合并js的情况,传输量大 1.1新建一个 [基本]的mvc项目 然后新建一个控制器HomeController,因为js会在很多视图中用到,所以此时我们添加一个视图带布局页Index ...

  5. [ NOIP 2014 ] TG

    \(\\\) \(Day\ 1\) \(\\\) \(\#\ A\) \(Rps\) 定义五种方案的石头剪刀布游戏,两人共进行\(N\)局游戏,已知两人各自的循环节和具体方案,胜者得\(1\)分,败者 ...

  6. 挂载硬盘,提示 mount: unknown filesystem type 'LVM2_member'的解决方案

    问题现象:由于重装linux,并且加了固态硬盘,直接将系统装在固态硬盘中.启动服务器的时候, 便看不到原来机械硬盘的挂载目录了,不知如何访问机械硬盘了.直接用命令 mount /dev/sda3 /s ...

  7. jQuery——链式编程与隐式迭代

    链式编程 1.原理:return this; 2.通常情况下,只有设置操作才能把链式编程延续下去.因为获取操作的时候,会返回获取到的相应的值,无法返回 this. 3.end():结束当前链最近的一次 ...

  8. js分页插件

    //分页插件1function showView(option) {    //参数定义id,页容量,当前页,总数,页总数    var id = option.id,         pageSiz ...

  9. PowerDesigner16逆向工程生成PDM列注释(My Sql5.0模版)

    一.编辑当前DataBase 选择DataBase——>edit Current DBMS...弹出如下对话框:  如上图,先解释一下: 根据红颜色框从上往下解释一下. 第一个红框是对应的修改的 ...

  10. 数据结构与算法(6) -- heap

    binary heap就是一种complete binary tree(完全二叉树).也就是说,整棵binary tree除了最底层的叶节点之外,都是满的.而最底层的叶节点由左至右又不得有空隙. 以上 ...