zoukankan      html  css  js  c++  java
  • hdu4183往返经过至多每个点一次/最大流

    题意:从s到t,每个点有f值,只能从f值小的到大的,到T后回来,只能从f值大的到 小的,求可行否。

    往返,其实就是俩条路过去(每个点最多一次),所以想到流量为2,跑最大流,看是否满2,又要每个点最多一次的条件,故每个点拆为2个,都是常用的。

    注意一下起点的拆点流量为2.

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxv=800,maxe=200101;
    int nume=0;int head[maxv];int e[maxe][3];
    void inline adde(int i,int j,int c)
    {
        e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
        e[nume++][2]=c;
        e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
        e[nume++][2]=0;
    }
    int ss,tt,n;
    int vis[maxv];int lev[maxv];
    bool bfs()
    {
        ss=0;
        for(int i=0;i<maxv;i++)
          vis[i]=lev[i]=0;
        queue<int>q;
        q.push(ss);
        vis[ss]=1;
        while(!q.empty())
        {
            int cur=q.front();
            q.pop();
            for(int i=head[cur];i!=-1;i=e[i][1])
            {
                int v=e[i][0];
                if(!vis[v]&&e[i][2]>0)
                {
                    lev[v]=lev[cur]+1;
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
        return vis[tt];
    }
    int dfs(int u,int minf)
    {
        if(u==tt||minf==0)return minf;
        int sumf=0,f;
        for(int i=head[u];i!=-1&&minf;i=e[i][1])
        {
            int v=e[i][0];
            if(lev[v]==lev[u]+1&&e[i][2]>0)
            {
                f=dfs(v,minf<e[i][2]?minf:e[i][2]);
                e[i][2]-=f;e[i^1][2]+=f;
                sumf+=f;minf-=f;
            }
        }
        if(!sumf) lev[u]=-1;
        return sumf;
    }
    int dinic()
    {
        int sum=0;
        while(bfs())sum+=dfs(ss,inf);
        return sum;
    }
    struct cir
    {
         double f;
         int r;
         int x,y;
    };
    cir pp[maxv];
    bool is_got(cir a,cir b)
    {
        int dis=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
        if(dis<(a.r+b.r)*(a.r+b.r)&&a.f<b.f)return 1;
        else return 0;
    }
    void read_build()
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%d%d%d",&pp[i].f,&pp[i].x,&pp[i].y,&pp[i].r);
    
            if(pp[i].f==400.0){ss=i; adde(i,i+n,2);}
            else  adde(i,i+n,1);
            if(pp[i].f==789.0)tt=i;
        }
        for(int i=1;i<=n;i++)
        {
          for(int j=1;j<=n;j++)
          {
              if(is_got(pp[i],pp[j]))
              {
                  adde(i+n,j,1);
              }
          }
        }
        adde(0,ss,2);
       /* for(int i=0;i<=n;i++)
          for(int j=head[i];j!=-1;j=e[j][1])
          {
              printf("%d->%d:%d
    ",i,e[j][0],e[j][2]);
          }*/
    }
    void init()
    {
        scanf("%d",&n);
        nume=0;
        memset(head,-1,sizeof(head));
        ss=0;tt=0;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            init();
            read_build();
            int ans=dinic();
            if(ans==2)printf("Game is VALID
    ");
            else printf("Game is NOT VALID
    ");
        }
    }
    


  • 相关阅读:
    pat00-自测5. Shuffling Machine (20)
    Spiral Matrix
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Best Time to Buy and Sell Stock II
    4Sum
    3Sum Closest
    3Sum
    MySQL存储过程、函数和游标
    Word Ladder
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925772.html
Copyright © 2011-2022 走看看