zoukankan      html  css  js  c++  java
  • HDU4183 Pahom on Water(来回走最大流,一个点只经过一次)

    题意:

    有n个圆,每个圆的中心和半径和一个频率都给定,只有一个频率最高的789为紫色,只有一个最低的400为红色,规则如下:

    1.当两个圆严格相交时,且人是从红色到紫色的方向运动时可以由低频率向高频率移动

    2.当两个圆严格相交时,且人是从紫色到红色的方向运动时可以由高频率向低频率运动

    3.除了红色的圆以外,离开某个圆之后就会消失(即只能走一次)

    思路:

    如果一开始红色和紫色就相交,则存在合理方案。否则

    本题要求是先从红点出发,经过紫点之后再返回红点,如果以红点作为源点,网络流算法不能先到达一个T,然后再到达另一个T,

    所以不妨以紫点作为源点sp,红点作为tp,将点拆分成i和i+n,然后建边(i, i+n, 1), (sp, sp+n, 2)如果两个圆严格相交,设i的频率

    大于j的频率,则(i+n, j, 1)反之(j+n, i, 1),求出最大流为2则存在合理方案。把S(紫色) -> T(红色)的两个流中的一个流反向,就可以形成一个

    T -> S -> T的方案。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 300 + 5;
    const int inf = 0x3f3f3f3f;
    struct point{
        double f;
        double x, y, r;
    } p[maxn];
    struct edge{
        int to, w, next;
    } ed[maxn*maxn<<2];
    int k, n, sp, tp;
    int head[maxn<<1], tot, d[maxn<<1], maxflow;
    inline void init(){
        memset( head, -1, sizeof(head) );
        tot = 1;
    }
    
    inline double getlen2( const point a, const point b ){
        double x1 = a.x, x2 = b.x;
        double y1 = a.y, y2 = b.y;
        return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    }
    
    inline bool judge(point a, point b){
        return getlen2(a, b) < (a.r+b.r)*(a.r+b.r);
    }
    
    inline void add( int u, int v, int w ){
        ed[++tot].to = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot;
        ed[++tot].to = u; ed[tot].w = 0; ed[tot].next = head[v]; head[v] = tot;
    }
    
    inline bool bfs(){
        memset( d, 0, sizeof(d) );
        queue<int> q;
        d[sp] = 1;
        q.push(sp);
        while( !q.empty() ){
            int x = q.front();
            q.pop();
            for( int i=head[x]; i!=-1; i=ed[i].next ){
                int y = ed[i].to;
                if( ed[i].w && !d[y] ){
                    d[y] = d[x] + 1;
                    q.push(y);
                    if( y==tp ) return 1;
                }
            }
        }
        return 0;
    }
    
    inline int dfs( int x, int flow ){
        if( x==tp ) return flow;
        int res = flow, k;
        for( int i=head[x]; i!=-1&&res; i=ed[i].next ){
            int y = ed[i].to;
            if( ed[i].w && d[y]==d[x]+1 ){
                k = dfs( y, min( res, ed[i].w ) );
                if(!k) d[y] = 0;
                ed[i].w -= k;
                ed[i^1].w += k;
                res -= k;
            }
        }
        return flow - res;
    }
    
    inline void dinic(){
        int flow = maxflow = 0;
        while( bfs() ){
            while( flow = dfs(sp, inf) ) maxflow += flow;
        }
    }
    
    int main(){
        // freopen("in.txt", "r", stdin);
        scanf("%d", &k);
        while( k-- ){
            scanf("%d", &n);
            init();
            for( int i=1; i<=n; i++ ){
                scanf("%lf%lf%lf%lf", &p[i].f, &p[i].x, &p[i].y, &p[i].r);
                if( p[i].f==400.0 ) tp = i;
                else if( p[i].f==789.0 ) sp = i;
                else add( i, i+n, 1 );
            }
            if( judge( p[sp], p[tp] ) ){
                puts("Game is VALID");
                continue;
            }
            add( sp, sp+n, 2 );
            for( int i=1; i<=n; i++ )
                for( int j=i+1; j<=n; j++ ){
                    if( judge(p[i], p[j]) ){
                        if( p[i].f<p[j].f ) add( j+n, i, 1 );
                        else add( i+n, j, 1 );
                    }
                }
            dinic();
            // cout << maxflow << endl;
            if( maxflow>=2 ) puts("Game is VALID");
            else puts("Game is NOT VALID");
        }
    
        return 0;
    }
    /*
    Game is NOT VALID
    Game is VALID
     */
  • 相关阅读:
    【leetcode】1295. Find Numbers with Even Number of Digits
    【leetcode】427. Construct Quad Tree
    【leetcode】1240. Tiling a Rectangle with the Fewest Squares
    【leetcode】1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    【leetcode】1291. Sequential Digits
    【leetcode】1290. Convert Binary Number in a Linked List to Integer
    【leetcode】1269. Number of Ways to Stay in the Same Place After Some Steps
    【leetcode】1289. Minimum Falling Path Sum II
    【leetcode】1288. Remove Covered Intervals
    【leetcode】1287. Element Appearing More Than 25% In Sorted Array
  • 原文地址:https://www.cnblogs.com/WAautomaton/p/11143483.html
Copyright © 2011-2022 走看看