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 }
时间: 2024-11-06 00:54:09

HDU 4183 Pahom on Water(最大流)的相关文章

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 来回走不重复点的网络流

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

【网络流】 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 <iost

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 EK最大流算法

欢迎参加——每周六晚的BestCoder(有米!) Pahom on Water Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 678    Accepted Submission(s): 312 Problem Description Pahom on Water is an interactive computer game ins

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 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