hdu 4183(网络流)

Posted AC菜鸟机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
 
题意:平面上有一些点,他们有着各自的坐标,频率,半径 ,可以从一个点到另一个点的条件是两点的距离小于半径之和,现在我们要从频率最小的点走到频率最大的点,规则是每次只能从频率小的走到频率大的,然后又要走回来,规则刚好是相反的,问是否存在这样一种方案使得上述条件成立。
题解:将第二个规则与第一个规则合并,问题就变成了是否存在两条不同的路使得起点(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");
    }
}

 

以上是关于hdu 4183(网络流)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4183 Pahom on Water(最大流)

hdu4183往返经过至多每一个点一次/最大流

HDU4183 Pahom on Water(来回走最大流,一个点只经过一次)

HDU 3452 Bonsai(网络流之最小割)

网络流强化-HDU2732

hdu4289城市与歹徒 网络流