hdu 4183 Pahom on Water (最大流)

来源:互联网 发布:网络彩票开售时间 编辑:程序博客网 时间:2024/06/12 11:19

Pahom on Water

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
 

题目大意:这道题主要是题意有些复杂,大致就是有n个圆,每个圆有频率,圆心,半径,两个有交点的圆之间可以走。要求从频率最小的圆走到最大的圆再走回来。每个圆只能走一次。


解题思路:这题的建图思路跟其他几道题比起来比较直接啦,直接按照题目要求从频率小的往频率大的连单向边,每条边的容量都是1.然后判断最后的最大流是不是大于2即可。


AC代码:

/** @Author: wchhlbt* @Last Modified t: 2017-10-17*/#include <bits/stdc++.h>#define inf 0x3f3f3f3f#define pb push_back#define AA first#define BB second#define ONES(x) __builtin_popcount(x)#define _  << "  " <<using namespace std;typedef pair<int, int> P;typedef long long ll ;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};const double eps =1e-8;const int mod = 1000000007;const double PI = acos(-1.0);inline int read(){ int num;    scanf("%d",&num);   return num;}const int maxn = 500;/*    最大流Dinic算法    使用前调用init函数*/struct Edge{    int from,to,cap,flow;    Edge(){}    Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){}};struct Dinic{    int n,m,s,t;    vector<Edge> edges;    vector<int> G[maxn];    bool vis[maxn];    int cur[maxn];    int d[maxn];    void init(int n,int s,int t)    {        this->n=n, this->s=s, this->t=t;        edges.clear();        for(int i=0;i<n;++i) G[i].clear();    }    void AddEdge(int from,int to,int cap)    {        edges.push_back( Edge(from,to,cap,0) );        edges.push_back( Edge(to,from,0,0) );        m=edges.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    bool BFS()    {        queue<int> Q;        memset(vis,0,sizeof(vis));        vis[s]=true;        d[s]=0;        Q.push(s);        while(!Q.empty())        {            int x=Q.front(); Q.pop();            for(int i=0;i<G[x].size();++i)            {                Edge& e=edges[G[x][i]];                if(!vis[e.to] && e.cap>e.flow)                {                    vis[e.to]=true;                    d[e.to]=d[x]+1;                    Q.push(e.to);                }            }        }        return vis[t];    }    int DFS(int x,int a)    {        if(x==t || a==0) return a;        int flow=0, f;        for(int &i=cur[x];i<G[x].size();++i)        {            Edge &e=edges[G[x][i]];            if(d[e.to]==d[x]+1 && ( f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)            {                e.flow +=f;                edges[G[x][i]^1].flow -=f;                flow +=f;                a -=f;                if(a==0) break;            }        }        return flow;    }    int max_flow()    {        int ans=0;        while(BFS())        {            memset(cur,0,sizeof(cur));            ans += DFS(s,inf);        }        return ans;    }}dinic;struct Node{    double f;    int x,y;    int r;}pad[maxn];bool cmp(Node a, Node b){    return a.f < b.f;}bool g[maxn][maxn];int sqr(int x){    return x*x;}int main(){    //ios::sync_with_stdio(false);    cin.tie(0);     int t = read();    while(t--){        memset(g,0,sizeof g);        int n = read();        for(int i = 0; i<n; i++){            scanf("%lf%d%d%d",&pad[i].f,&pad[i].x,&pad[i].y,&pad[i].r);        }        dinic.init(n,0,n-1);        sort(pad,pad+n,cmp);        for(int i = 0; i<n; i++){            for(int j = i+1; j<n; j++){                if(sqr(pad[i].x-pad[j].x)+sqr(pad[i].y-pad[j].y)<=sqr(pad[i].r+pad[j].r)){                    //cout << i _ j << endl;                    dinic.AddEdge(i,j,1);                }            }        }        int full_flow = dinic.max_flow();        if(full_flow>=2)    puts("Game is VALID");        else    puts("Game is NOT VALID");    }    return 0;}/*unsigned   int   0~4294967295int   2147483648~2147483647unsigned long 0~4294967295long   2147483648~2147483647long long的最大值:9223372036854775807long long的最小值:-9223372036854775808unsigned long long的最大值:18446744073709551615__int64的最大值:9223372036854775807__int64的最小值:-9223372036854775808unsigned __int64的最大值:18446744073709551615*/

原创粉丝点击