hdu 4183(网络流)

Pahom on Water

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 885    Accepted Submission(s): 409

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

The 2011 South Pacific Programming Contest

题意:平面上有一些点,他们有着各自的坐标,频率,半径 ,可以从一个点到另一个点的条件是两点的距离小于半径之和,现在我们要从频率最小的点走到频率最大的点,规则是每次只能从频率小的走到频率大的,然后又要走回来,规则刚好是相反的,问是否存在这样一种方案使得上述条件成立。

题解:将第二个规则与第一个规则合并,问题就变成了是否存在两条不同的路使得起点(f最低)能够到达终点(f最高)先对所有点按照频率排序,然后构图,频率低的向频率高的连一条容量为1的边,这样的话就能够保证每条边最多走一次,然后求一次最大流,如果最大流大于等于2就存在这样的两条路。

#include <stdio.h>
#include <algorithm>
#include <queue>
#include <string.h>
#include <math.h>
using namespace std;
const int N = 350;
const int INF = 999999999;
int cap[N][N];
int flow[N];
int pre[N];
int n;
struct Node{
    int x,y,r;
    double f;
}node[N];
double dis(Node a,Node b){
    return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
}
int bfs(int src,int des){
    queue<int> q;
    for(int i=1;i<=des;i++){
        pre[i]=-1;
    }
    pre[src]=0;
    flow[src]=INF;
    q.push(src);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        if(u==des) break;
        for(int i=1;i<=des;i++){
            if(i!=src&&cap[u][i]>0&&pre[i]==-1){
                pre[i] = u;
                flow[i] = min(cap[u][i],flow[u]);
                q.push(i);
            }
        }
    }
    if(pre[des]==-1) return -1;
    return flow[des];
}

int max_flow(int src,int des){
    int ans = 0,increaseRoad;
    while((increaseRoad=bfs(src,des))!=-1){
        int k = des;
        while(k!=src){
            cap[pre[k]][k]-=increaseRoad;
            cap[k][pre[k]]+=increaseRoad;
            k = pre[k];
        }
        ans+=increaseRoad;
    }
    return ans;
}
int cmp(Node a,Node b){
    return a.f<b.f;
}
void build(){
    scanf("%d",&n);
    memset(cap,0,sizeof(cap));
    for(int i=1;i<=n;i++){
        scanf("%lf%d%d%d",&node[i].f,&node[i].x,&node[i].y,&node[i].r);
    }
    sort(node+1,node+n+1,cmp);
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(i!=j&&dis(node[i],node[j])<=(node[i].r+node[j].r)){
                cap[i][j]=1;
            }
        }
    }
}
int main(){
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        build();
        int t = max_flow(1,n);
        if(t>=2) printf("Game is VALID\n");
        else printf("Game is NOT VALID\n");
    }
}
时间: 2024-10-07 05:45:54

hdu 4183(网络流)的相关文章

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

题目来源:HDU 4183 Pahom on Water 题意:若干个区域 每个区域有一个值 区域是圆 给出圆心和半径 从起点(值为400.0)到终点(值为789.0)满足走相交的圆 并且值必须递增 然后从终点到起点 值必须递减 此外区域只能去一次 思路:建图 相互能走的区域连一条边 因为只能走一次 所以拆点 如果没有来回 只有去 那么判断最大流为1即可 现在还要回来 并且回来的条件和去的条件想法(一个递增一个递减)可以反向考虑给源点cap=2 最大流为2 #include <cstdio>

HDU 3488Tour(网络流之最小费用流)

题目地址:hdu3488 这题跟上题基本差不多啊....详情请戳这里. 另外我觉得有要改变下代码风格了..终于知道了为什么大牛们的代码的变量名都命名的那么长..我决定还是把源点与汇点改成source和sink吧..用s和t太容易冲突了...于是如此简单的一道题调试到了现在..sad... 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #

HDU 4292Food(网络流之最大流)

题目地址:HDU 4292 水题. 由于每个人只能有1份,所以需要拆点限制流量.建图方法为,建一源点与汇点,将食物与源点相连,权值为食物额数量,将饮料与汇点相连,权值为饮料数量..然后将人进行拆点为i和i',将对应的i与i'连边权值为1,将i与它所对应的YES的食物连边,将i'与它所对应的YES的饮料连边,一次求最大流. 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include &

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

题意:求两条路 能从 400.0 -> 789.0 且这两条路不想交(除了端点400,789 ) 求只能走一次的网络流需要用到拆点, 将点i  拆成 i 和 i+n  i->i+n的容量为经过的次数  (这题为1 ) 若i 能到达 j  则连接 i+n-> j #include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iost

kebab (hdu 2883 网络流判满流 关键是缩点)

kebab Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1071    Accepted Submission(s): 447 Problem Description Almost everyone likes kebabs nowadays (Here a kebab means pieces of meat grilled on

HDU 4888 (网络流)

Poroblem Redraw Beautiful Drawings (HDU4888) 题目大意 一个n行m列的矩形,只能填0~k的数字. 给定各行各列的数字和,判定有无合法的方案数.一解给出方案,多解输出给定字符串. 解题分析 一个经典的网络流建图. 由S向行连流量为该行数字和的边,由列向T连流量为该列数字和的边,从行向列连流量为k的边. 若满流说明有解. 在残余网络中从每个点开始dfs,若找到一个点数大于2的环,说明有多解. 参考程序 1 #include <cstdio> 2 #inc

Food (hdu 4292 网络流sap模板题)

Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3102    Accepted Submission(s): 1034 Problem Description You, a part-time dining service worker in your college's dining hall, are now confu

hdu 1565&amp;hdu 1569(网络流--最小点权值覆盖)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7717    Accepted Submission(s): 2911 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数

HDU 1083 网络流之二分图匹配

http://acm.hdu.edu.cn/showproblem.php?pid=1083 二分图匹配用得很多 这道题只需要简化的二分匹配 #include<iostream> #include<cstdio> #include<cstring> #define maxm 410 using namespace std; int p,n; int master[maxm]; int linking[maxm][maxm]; int has[maxm]; int sol