zoukankan      html  css  js  c++  java
  • hdu 4183 EK最大流算法

    Pahom on Water

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


    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
     

    这题题目意思很难看懂。。我看了好长时间也没看懂。。最终是从网上找的翻译。。我就在这翻译一下吧。

    意思大约是:有多个点,每个点给出坐标与半径,加入两个点相交,就可以从这两个点走。题目要求先从起点到终点,再从终点回到起点。从起点到终点的过 程中,只能从频率小的走到频率大的点(前提是两点相交),从终点到起点的过程中,只能从频率大的走到频率小的。在走的过程中,除了起点与终点,别的只要走 过就会消失,就是说只能走一次。问可不可以从起点到终点又回到起点。

    初一看没什么思路,后来一想,无非就是从起点到终点走两次,均是从小到大,而且中间经过的点不重复即可。然后建图就很简单了。为了保证每个点只走一 次,可以把权值设为1,这样每一步最多只能走一次。然后看最大流是否大于等于2即可。还有一点需要注意的是,如果可以直接从起点到终点的话,就不用判断 了,肯定可以满足要求。

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int inf=0x7fffffff;
    int edge[500][500];//邻接矩阵
    int dis[500];//距源点距离,分层图
    int start,end;
    int m,n;//N:点数;M,边数
    struct node{
      double s;
      int x,y,r;
    }que[500];
    bool con(int i,int j){
          if(((que[i].x-que[j].x)*(que[i].x-que[j].x)+(que[i].y-que[j].y)*(que[i].y-que[j].y))<(que[i].r+que[j].r)*(que[i].r+que[j].r))
          return true;
          else
            return false;
    }
    
    int maxflow, pre[500];
    void Edmonds_Karp(int start, int end, int m){
        while(1)
        {
            queue<int>p;
            int minflow = inf;
            p.push(start);
            memset(pre, 0, sizeof(pre));
            while(!p.empty()){
                int u = p.front();
                p.pop();
                if(u == end)
                    break;
                for(int i = 1;i <= m;i++)
                    if(edge[u][i] > 0&&pre[i] == 0){
                        pre[i] = u;
                        p.push(i);
                    }
            }
            if(pre[end] == 0)
                break;
            for(int i = end;i != start;i = pre[i])
                minflow = min(minflow, edge[pre[i]][i]);
            for(int i = end;i != start;i = pre[i])    {
                edge[pre[i]][i] -= minflow;
                edge[i][pre[i]] += minflow;
            }
            maxflow+=minflow;
        }
    }
    int main(){
    
        int t;
        scanf("%d",&t);
       while(t--){
            memset(que,0,sizeof(que));
           memset(edge,0,sizeof(edge));
           int n;
           scanf("%d",&n);
           for(int i=1;i<=n;i++){
              scanf("%lf%d%d%d",&que[i].s,&que[i].x,&que[i].y,&que[i].r);
           }
    
           for(int i=1;i<=n;i++){
               if(que[i].s==400.0){
               start=i;
                }
                if(que[i].s==789.0){
                   end=i;
                }
    
           }
    
           for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                if(con(i,j)){
                   if(que[i].s>que[j].s)
                        edge[j][i]=1;
                   else if(que[j].s>que[i].s)
                        edge[i][j]=1;
                }
            }
           }
          maxflow = 0;
            Edmonds_Karp(start, end, n);
           if(maxflow>=2)
              printf("Game is VALID
    ");
             else
        printf("Game is NOT VALID
    ");
       }
       return 0;
    }
  • 相关阅读:
    Net163网页测试
    单片机无线上网的几种方式
    5V到3V3的电平转换-串口通信
    uart rs232 rs485
    转:TI公司CC系列的各种芯片的区别
    OpenWrt 路由器固件
    cortex-m4 不能运行Linux, 可以运行 uclinux, ucos iii
    Lwip Uip
    Java-06-交换两个变量的值
    Java-05-比较equals()与== [转载]
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4729098.html
Copyright © 2011-2022 走看看