首页 > 代码库 > HDU 4183 Pahom on Water(最大流)

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\n");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\n");160         else printf("Game is NOT VALID\n");161     }162     return 0;163 }

 

HDU 4183 Pahom on Water(最大流)