HDU 4183--Pahom on Water【最大流dinic】

来源:互联网 发布:catiav5r22软件下载 编辑:程序博客网 时间:2024/06/08 10:19

Pahom on Water

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


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
22 400.0 0 0 4789.0 7 0 24400.0 0 0 4789.0 7 0 2500.35 5 0 2500.32 5 0 3
 

Sample Output
Game is NOT VALIDGame is VALID
 

题意:水面上有很多的圆形区域,他们要么存在相交的区域,要么不存在相交的区域,不会存在相切的情况。每个区域都有颜色,并且告诉你每个区域颜色的频率。现在要求你从唯一的一个红色区域(频率最小)走到紫色区域(频率最大)并从紫色区域返回红色区域。并且必须遵循以下三个规则:(1)从红色走到紫色的时候,必须从频率小的区域走向频率大的区域。(2)从紫色走到红色的时候,必须从频率大的区域走向频率小的区域。(3)除了初始的红色区域,你每离开一个区域的时候,那个区域都会消失。问你是否存在一个合法的方式。


思路:转化为从起点到终点走两次,均是从小到大,而且中间经过的点不重复即可。设超级源点 0, 连到 THz为789的点, 权值为2, THz为400的点连到 汇点, 权值也为2,  其余的点之间看看是否符合条件,符合条件的话两两相连,权值设为1.

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <iostream>#include <cmath>#define maxn 1100#define maxm 220000#define dd double#define INF 0x3f3f3f3fusing namespace std;int n;int head[maxn], cur[maxn], cnt;int vis[maxn], dist[maxn];struct node{    int u, v, cap, flow, next;};node edge[maxm];struct map{    dd THz, x, y, r;};map str[maxn];void init(){    cnt = 0;    memset(head, -1, sizeof(head));}void add(int u, int v, int w){    edge[cnt] = {u, v, w, 0, head[u]};    head[u] = cnt++;    edge[cnt] = {v, u, 0, 0, head[v]};    head[v] = cnt++;}bool check(map a, map b){    if((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) < (a.r + b.r) * (a.r + b. r) && a.THz > b.THz)        return true;    else        return false;}void getmap(){    for(int i = 1; i <= n; ++i){        if(abs(str[i].THz - 789.0) <= 1e-6){            add(0, i, 2);        }        if(abs(str[i].THz - 400.0) <= 1e-6){            add(i, n + 1, 2);        }        for(int j = 1; j <= n; ++j){            if(j == i) continue;            if(check(str[i], str[j]))                add(i, j, 1);        }    }}bool BFS(int st, int ed){    queue<int>q;    memset(vis, 0, sizeof(vis));    memset(dist, -1, sizeof(dist));    vis[st] = 1;    dist[st] = 0;    q.push(st);    while(!q.empty()){        int u =q.front();        q.pop();        for(int i = head[u]; i != -1; i = edge[i].next){            node E = edge[i];            if(!vis[E.v] && E.cap > E.flow){                vis[E.v] = 1;                dist[E.v] = dist[u] + 1;                if(E.v == ed) return true;                q.push(E.v);            }        }    }    return false;}int DFS(int x, int ed, int a){    if(x == ed || a == 0)        return a;    int flow = 0, f;    for(int &i = cur[x]; i != -1; i = edge[i].next){        node &E = edge[i];        if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){            E.flow += f;            edge[i ^ 1].flow -= f;            a -= f;            flow += f;            if(a == 0) break;        }    }    return flow;}int maxflow(int st, int ed){    int flowsum = 0;    while(BFS(st, ed)){        memcpy(cur, head, sizeof(head));        flowsum += DFS(st, ed, INF);    }    return flowsum;}int main (){    int T;    scanf("%d", &T);    while(T--){        scanf("%d", &n);        for(int i = 1; i <= n ;++i)            scanf("%lf%lf%lf%lf", &str[i].THz, &str[i].x, &str[i].y, &str[i].r);        init();        getmap();        if(maxflow(0, n + 1) == 2)            printf("Game is VALID\n");        else            printf("Game is NOT VALID\n");    }    return 0;}


0 0
原创粉丝点击