• HDU 4183 Pahom on Water(最大流)


    https://vjudge.net/problem/HDU-4183

    题意:

    这道题目的英文实在是很难理解啊。

    给出n个圆,每个圆有频率,x、y轴和半径r4个属性,每次将频率为400的圆作为起点,频率为789点作为终点。从源点到汇点时必须从频率小的到频率大的,而从汇点到源点时必须从频率大的到频率小的。前提时这两个圆必须严格相交。每个点只能走一次。判断是否能从起点出发到达终点,并再次返回起点。

    思路:

    其实就是判断最大流是否大于等于2。因为每个点只能走一次,用拆点法。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 
      8 const int maxn=1000+5;
      9 const int INF=0x3f3f3f3f;
     10 
     11 struct Point
     12 {
     13   double p;
     14   int x,y,r;
     15 }point[maxn],s,t;
     16 
     17 bool cacl(Point a,Point b)
     18 {
     19     double l1=(b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x);
     20     double l2=(double)(a.r+b.r)*(a.r+b.r);
     21     if(l1<l2)  return true;
     22     else return false;
     23 }
     24 
     25 struct Edge
     26 {
     27     int from,to,cap,flow;
     28     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
     29 };
     30 
     31 struct Dinic
     32 {
     33     int n,m,s,t;
     34     vector<Edge> edges;
     35     vector<int> G[maxn];
     36     bool vis[maxn];
     37     int cur[maxn];
     38     int d[maxn];
     39 
     40     void init(int n)
     41     {
     42         this->n=n;
     43         for(int i=0;i<n;++i) G[i].clear();
     44         edges.clear();
     45     }
     46 
     47     void AddEdge(int from,int to,int cap)
     48     {
     49         edges.push_back( Edge(from,to,cap,0) );
     50         edges.push_back( Edge(to,from,0,0) );
     51         m=edges.size();
     52         G[from].push_back(m-2);
     53         G[to].push_back(m-1);
     54     }
     55 
     56     bool BFS()
     57     {
     58         queue<int> Q;
     59         memset(vis,0,sizeof(vis));
     60         vis[s]=true;
     61         d[s]=0;
     62         Q.push(s);
     63         while(!Q.empty())
     64         {
     65             int x=Q.front(); Q.pop();
     66             for(int i=0;i<G[x].size();++i)
     67             {
     68                 Edge& e=edges[G[x][i]];
     69                 if(!vis[e.to] && e.cap>e.flow)
     70                 {
     71                     vis[e.to]=true;
     72                     d[e.to]=d[x]+1;
     73                     Q.push(e.to);
     74                 }
     75             }
     76         }
     77         return vis[t];
     78     }
     79 
     80     int DFS(int x,int a)
     81     {
     82         if(x==t || a==0) return a;
     83         int flow=0, f;
     84         for(int &i=cur[x];i<G[x].size();++i)
     85         {
     86             Edge &e=edges[G[x][i]];
     87             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
     88             {
     89                 e.flow +=f;
     90                 edges[G[x][i]^1].flow -=f;
     91                 flow +=f;
     92                 a -=f;
     93                 if(a==0) break;
     94             }
     95         }
     96         return flow;
     97     }
     98 
     99     int Maxflow(int s,int t)
    100     {
    101         this->s=s; this->t=t;
    102         int flow=0;
    103         while(BFS())
    104         {
    105             memset(cur,0,sizeof(cur));
    106             flow +=DFS(s,INF);
    107         }
    108         return flow;
    109     }
    110 }DC;
    111 
    112 int n;
    113 
    114 int main()
    115 {
    116     //freopen("D:\input.txt","r",stdin);
    117     int T;
    118     scanf("%d",&T);
    119     while(T--)
    120     {
    121         scanf("%d",&n);
    122         DC.init(2*n+10);
    123         for(int i=1;i<=n;i++)
    124         {
    125             scanf("%lf%d%d%d",&point[i].p,&point[i].x,&point[i].y,&point[i].r);
    126             if(point[i].p==400)
    127             {
    128                 s=point[i];
    129                 i--;
    130                 n--;
    131             }
    132             else if(point[i].p==789)
    133             {
    134                 t=point[i];
    135                 i--;
    136                 n--;
    137             }
    138         }
    139 
    140         if(cacl(s,t))
    141         {
    142             printf("Game is VALID
    ");
    143             continue;
    144         }
    145 
    146         for(int i=1;i<=n;i++)
    147         {
    148             DC.AddEdge(i,n+i,1);   //拆点
    149             if(cacl(s,point[i]) && s.p<point[i].p)  DC.AddEdge(0,i,1);
    150             if(cacl(point[i],t) && point[i].p<t.p)  DC.AddEdge(n+i,2*n+1,1);
    151             for(int j=1;j<=n;j++)
    152             {
    153                 if(i==j)    continue;
    154                 if(cacl(point[i],point[j]) && point[i].p<point[j].p)
    155                     DC.AddEdge(n+i,j,1);
    156             }
    157         }
    158         int ans=DC.Maxflow(0,2*n+1);
    159         if(ans>=2)   printf("Game is VALID
    ");
    160         else printf("Game is NOT VALID
    ");
    161     }
    162     return 0;
    163 }
  • 相关阅读:
    WPF中调用资源字典的方法
    DataGridView控制单元格修改的输入规则
    将dataGridView数据转成DataTable
    窗体打开后设置某个控件为默认的焦点
    自定义控件属性英文类别
    VMWare虚拟机与主机建立共享文件夹
    与.Net大师Jeffrey Richter面对面交流——TUP对话大师系列活动回顾(多图配详细文字)
    一个编程小题目引发的思考(下)
    一个Quicksort究竟可以写到多么短
    我是如何设计并实现一门程序设计语言——一门函数式编程语言Lucida的诞生
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6686245.html
Copyright © 2020-2023  润新知