杭电多校联合第一场hdu4606 occupy cities
来源:互联网 发布:程序员都有什么app 编辑:程序博客网 时间:2024/06/07 14:14
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4606
题目翻译:在平面上,有n个城市,m个障碍,p个士兵,然后士兵要按照一定的顺序到达城市,士兵在第一次的时候后可以降落在任何一个城市。士兵从城市A 到达城市B 是不能越过障碍,障碍为线段。求士兵走的每路程中每一段的最大值的最小。
分析:前面可以将障碍分成一个个的点,然后判断城市之间的路程与障碍的线段相交,求出每个城市之间的路程,然后就是求图的最小路径覆盖数。二分最大值,按照到达的顺序做成有向边,求最大匹配,然后将城市数目和最大匹配相减与士兵数比较即可(前面的计算几何不会,比赛中没有搞出来。。sad)剩下的都是模板了。。
代码是抄的标程。。。我太水了。。
#include<stdio.h>#include<string.h>#include<algorithm>#include<cmath>#define N 110#define M 210#define eps 1e-8#define CC(x,y) memset(x,y,sizeof(x))#define inf 1e15#define db doubleusing namespace std;struct point{ db x,y; point() {} point(db a,db b):x(a),y(b) {} point operator - (const point p) { return point (x-p.x,y-p.y); }};int dlcmp(double x){ return x<-eps?-1:x>eps;}double sqr(double x){ return x*x;}db dist(point a,point b){ return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}db cross(point a,point b){ return a.x*b.y-a.y*b.x;}int n,m,p,seq[N],match[N],map[N][N],link[N],i,j,k,x,y,z;db dis[N+M][N+M];point pt[N+M];int segment_intersect(point s1,point e1,point s2,point e2){ if (max(s1.x,e1.x)>min(s2.x,e2.x)&&max(s2.x,e2.x)>min(s1.x,e1.x)&& max(s1.y,e1.y)>min(s2.y,e2.y)&&max(s2.y,e2.y)>min(s1.y,e1.y)&& dlcmp(cross(e1-s1,s2-s1))*dlcmp(cross(e1-s1,e2-s1))<0&& dlcmp(cross(e2-s2,s1-s2))*dlcmp(cross(e2-s2,e1-s2))<0) return 1; return 0;}bool isBlock(point a,point b){ for (int i=1; i<=m; i++) if (segment_intersect(a,b,pt[i+n],pt[i+n+m])) return 1; return 0;}db floyed(){ int i,j,k; int num=n+m+m; for (i=1; i<=num; i++) for (j=1; j<=num; j++) dis[i][j]=dis[j][i]=(i==j)?0:inf; for (i=1; i<=num; i++) for (j=i+1; j<=num; j++) if (!isBlock(pt[i],pt[j])) dis[i][j]=dis[j][i]=dist(pt[i],pt[j]); for (int k=1; k<=num; k++) for (int i=1; i<=num; i++) for (int j=1; j<=num; j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); db res=0; for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) res=max(res,dis[i][j]); return res;}bool dfs(int x){ int i; for (i=1; i<=n; i++) if (match[i]==0&&map[x][i]) { match[i]=1; if (link[i]==0||dfs(link[i])) { link[i]=x; return 1; } } return 0;}bool check(double x){ CC(map,0); for (i=1; i<=n; i++) for (j=1; j<=n; j++) if (dis[i][j]-x<=eps&&seq[i]<seq[j]) map[i][j]=1; CC(link,0); int ans=0; for (i=1; i<=n; i++) { CC(match,0); if (dfs(i))ans++; } if (n-ans<=p)return 1; return 0;}int main(){ int tt; scanf("%d",&tt); while (tt--) { scanf("%d%d%d",&n,&m,&p); for (int i=1; i<=n; i++) scanf("%lf%lf",&pt[i].x,&pt[i].y); for (int i=1; i<=m; i++) scanf("%lf%lf%lf%lf",&pt[n+i].x,&pt[n+i].y,&pt[n+i+m].x,&pt[n+i+m].y); for (i=1; i<=n; i++) { scanf("%d",&x); seq[x]=i; } db l=0,r=floyed(); while ((r-l)>eps) { db mid=(r+l)/2; if (check(mid))r=mid; else l=mid; } printf("%.2lf\n",l); } return 0;}
- 杭电多校联合第一场hdu4606 occupy cities
- HDU4606 Occupy Cities 计算几何+最小路径覆盖
- hdu4606 Occupy Cities简单计算几何+floyd+最小路径覆盖+二分答案
- hdu4606 Occupy Citie 简单计算几何,最小路径覆盖
- 2013年多校联合第一场
- 2014杭电多校联合第一场Task(贪心+STL使用)
- HDU 4606 Occupy Cities 解题报告
- 2014多校联合第一场
- 多校联合第一场 数学
- 2016年多校联合训练第一场
- 2013 Multi-University Training Contest 1 Occupy Cities HDU 4606
- hdu 4606 Occupy Cities(几何+二分+KM)
- hdu5288 多校联合第一场第一题
- 2014杭电多校联合第一场Jump费用流(最小K路径覆盖)
- HDU1010 && 多校联合第一场H题
- hdu 4602 partition 2013多校联合训练第一场
- 多校联合赛 第一场
- 2014多校联合第一场 1004 Task
- UITableView 使用小结
- XFire实现WebService一:使用XfireConfigurableServlet
- 自己动手写Django app,第四部分【全剧终】
- 反向键索引研究
- 解决SurfaceView设置透明造成覆盖其他组件的替代方案
- 杭电多校联合第一场hdu4606 occupy cities
- hdu 1254 推箱子
- linux下如何生成任意大小的测试文件
- Windows和linux下的Java串口开发( javacomm20/RXTX)
- Mysql命令行操作
- 5.时间日期模块--python笔记
- GUI(图形用户界面)
- 贪心算法
- hdu1010Tempter of the Bone