【网络流】 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 <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <time.h>;
#define cler(arr, val)    memset(arr, val, sizeof(arr))
#define FOR(i,a,b)  for(int i=a;i<=b;i++)
#define IN   freopen ("in.txt" , "r" , stdin);
#define OUT  freopen ("out.txt" , "w" , stdout);
typedef long long  LL;
const int MAXN = 514;
const int MAXM = 40101;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
struct Edge
{
    int to,next,cap,flow;
} edge[MAXM]; //注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN];
void init()
{
    tol = 0;
    memset(head,-1,sizeof (head));
}
void addedge (int u,int v,int w,int rw = 0)
{
    edge[tol].to = v;
    edge[tol].cap = w;
    edge[tol].flow = 0;
    edge[tol].next = head[u];
    head[u] = tol++;
    edge[tol].to = u;
    edge[tol].cap = rw;
    edge[tol].flow = 0;
    edge[tol].next = head[v];
    head[v] = tol++;
}
int Q[MAXN];
void BFS(int start,int end)
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0] = 1;
    int front = 0, rear = 0;
    dep[end] = 0;
    Q[rear++] = end;
    while(front != rear)
    {
        int u = Q[front++];
        for(int i = head[u]; i !=  -1; i = edge[i].next)
        {
            int v = edge[i]. to;
            if(dep[v] != -1)continue;
            Q[rear++] = v;
            dep[v] = dep[u] + 1;
            gap[dep[v]]++;
        }
    }
}
int S[MAXN];
int sap(int start,int end, int N)
{
    BFS(start,end);
    memcpy(cur,head,sizeof(head));
    int top = 0;
    int u = start;
    int ans = 0;
    int i;
    while(dep[start] < N)
    {
        if(u == end)
        {
            int Min = INF;
            int inser;
            for( i = 0; i < top; i++)
            {
                if(Min > edge[S[i]].cap - edge[S[i]].flow)
                {
                    Min = edge[S[i]].cap - edge[S[i]].flow;
                    inser = i;
                }
            }
            for( i = 0; i < top; i++)
            {
                edge[S[i]]. flow += Min;
                edge[S[i]^1].flow -= Min;
            }
            ans += Min;
            top = inser;
            u = edge[S[top]^1].to;
            continue;
        }
        bool flag =  false;
        int v;
        for( i = cur[u]; i != -1; i = edge[i]. next)
        {
            v = edge[i]. to;
            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])
            {
                flag =  true;
                cur[u] = i;
                break;
            }
        }
        if(flag)
        {
            S[top++] = cur[u];
            u = v;
            continue;
        }
        int Min = N;
        for( i = head[u]; i !=  -1; i = edge[i].next)
        {
            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
            {
                Min = dep[edge[i].to];
                cur[u] = i;
            }
        }
        gap[dep[u]]--;
        if(!gap[dep[u]]) return ans;
        dep[u] = Min + 1;
        gap[dep[u]]++;
        if(u != start)u = edge[S[--top]^1].to;
    }
    return ans;
}
double gao(double x,double y,double a,double b)
{
    return sqrt((x-a)*(x-a)+(y-b)*(y-b));
}
struct point
{
    double f,x,y,r;
    point(){};
}a[202];
bool cmp(point a,point b)
{
    return a.f<b.f;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf%lf%lf",&a[i].f,&a[i].x,&a[i].y,&a[i].r);
        sort(a,a+n,cmp);
        addedge(0,n,1);
        addedge(n-1,2*n-1,1);
        for(int i=0;i<n;i++)
        {
            addedge(i,i+n,1);
            for(int j=i+1;j<n;j++)
            {
                if(a[i].f<a[j].f&&gao(a[i].x,a[i].y,a[j].x,a[j].y)<(a[i].r+a[j].r))
                    addedge(i+n,j,1);
            }
        }
        if(sap(0,2*n-1,2*n)==2)
            puts("Game is VALID");
        else puts("Game is NOT VALID");

    }
    return 0;
}
时间: 2024-08-06 11:54:48

【网络流】 HDU 4183 Pahom on Water 拆点的相关文章

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

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

HDU 4183 Pahom on Water(最大流SAP)

Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 629    Accepted Submission(s): 288 Problem Description Pahom on Water is an interactive computer game inspired by a short story of

HDU 4183 Pahom on Water(最大流)

https://vjudge.net/problem/HDU-4183 题意: 这道题目的英文实在是很难理解啊. 给出n个圆,每个圆有频率,x.y轴和半径r4个属性,每次将频率为400的圆作为起点,频率为789点作为终点.从源点到汇点时必须从频率小的到频率大的,而从汇点到源点时必须从频率大的到频率小的.前提时这两个圆必须严格相交.每个点只能走一次.判断是否能从起点出发到达终点,并再次返回起点. 思路: 其实就是判断最大流是否大于等于2.因为每个点只能走一次,用拆点法. 1 #include<io

hdoj 4183 Pahom on Water 【基础最大流】

题目:hdoj 4183 Pahom on Water 题意:题目有点长,读懂了就是个水的最大流,每次从789开始到400,走的话必须是两个圆相交而且频率递增的,每个点只走一次,求有没有满足这样条件的. 分析:题目读懂就比较水了.直接按照题目意思建图,初始点和结束点容量为2,其他点只走一次容量为1,然后求最大流. AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <str

hdoj 4183 Pahom on Water

Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 772    Accepted Submission(s): 355 Problem Description Pahom on Water is an interactive computer game inspired by a short story of

【HDOJ】4183 Pahom on Water

就是一个网络流.red结点容量为2,查看最大流量是否大于等于2.对于条件2,把边反向加入建图.条件1,边正向加入建图. 1 /* 4183 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #inc

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

hdu 4292 Food 最大流+拆点

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

hdu 4974 A simple water problem(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4974 Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or