hdu4606 Occupy Cities简单计算几何+floyd+最小路径覆盖+二分答案
来源:互联网 发布:python输入ctrl c 编辑:程序博客网 时间:2024/06/05 02:56
借鉴这里:http://www.cnblogs.com/wangfang20/archive/2013/07/25/3213628.html
有n个城市,m个边界线,p名士兵。现在士兵要按一定顺序攻占城市,不能穿过一些线段。士兵有一个容量为K的背包装粮食,士兵如果攻占城市,就能装满背包。从城市到城市消耗的粮食等于两城市的距离,如果距离大于士兵当前的背包的容量,士兵就不能走这条路。求p个士兵攻占完所有城市所需要的最小背包容量k。
二分答案 , 将所有的直线的两个端点和城市混在一起,将能直接到达的两个点连线,求一次floyd最短路径。二分枚举bag容量,只需要判断最小路径覆盖是否小于等于p,就是最少需要多少个士兵才能全部占领
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define clr(x) memset(x,0,sizeof(x));#define INF 0x1f1f1f1f#define maxn 510#define maxm 510#define eps 1e-6struct Point{ double x; double y;}city[maxn];struct Edge{ Point a,b;}edge[maxm];int ord[maxn];double d[maxn+maxm*2][maxn+maxm*2];int n,m,p;double multi(Point p0, Point p1, Point p2){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}double Dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}bool isIntersected(Point s1,Point e1,Point s2,Point e2){ //判断线段是否相交(非规范相交) return multi(s1,e1,s2)*multi(s1,e1,e2)<-eps&& multi(s2,e2,s1)*multi(s2,e2,e1)<-eps;}int g[maxn][maxn];int v[maxn];int link[maxn];int find(int k){ int i; for(i=1;i<=n;i++){ if(g[k][i]&&!v[i]){ v[i]=1; if(link[i]==0||find(link[i])){ link[i]=k; return 1; } } } return 0;}int maxmatch(){ int i; clr(link); int res=0; for(i=1;i<=n;i++){ clr(v); if(find(i))res++; } return n-res;}int main(){ int T,tot,i,j,k; scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&p); for(i=1;i<=n;i++) scanf("%lf%lf",&city[i].x,&city[i].y); tot=n; for(i=1;i<=m;i++){ scanf("%lf%lf%lf%lf",&edge[i].a.x,&edge[i].a.y,&edge[i].b.x,&edge[i].b.y); city[++tot].x=edge[i].a.x;city[tot].y=edge[i].a.y; city[++tot].x=edge[i].b.x;city[tot].y=edge[i].b.y; } for(i=1;i<=n;i++) scanf("%d",&ord[i]); for(i=1;i<=tot;i++) for(j=1;j<=tot;j++) d[i][j]=INF; for(i=1;i<tot;i++){ for(j=i+1;j<=tot;j++){ int flag=0; for(k=1;k<=m;k++) if(isIntersected(city[i],city[j],edge[k].a,edge[k].b)){ flag=1;break; } if(flag==0)d[i][j]=d[j][i]=Dis(city[i],city[j]); } } for(k=1;k<=tot;k++) for(i=1;i<=tot;i++) for(j=1;j<=tot;j++){ d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } double maxlen=0.0; for(i=1;i<=n;i++) for(j=1;j<=n;j++){ if(d[i][j]<INF)maxlen=max(d[i][j],maxlen); } double mid,l=0,r=maxlen; while(r-l>eps){ mid=(l+r)/2; clr(g); for(i=1;i<n;i++) for(j=i+1;j<=n;j++){ if(d[ord[i]][ord[j]]<=mid) g[ord[i]][ord[j]]=1; } if(maxmatch()<=p)r=mid; else l=mid; } printf("%.2lf\n",r); } return 0;}
- hdu4606 Occupy Cities简单计算几何+floyd+最小路径覆盖+二分答案
- HDU4606 Occupy Cities 计算几何+最小路径覆盖
- hdu4606 Occupy Citie 简单计算几何,最小路径覆盖
- HDU 4606 Occupy Cities (计算几何+Floyd+二分+最小路径覆盖)
- HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)
- hdu 4606 Occupy Cities - 计算几何 + 最短路 + 最小路径覆盖
- hdu 4606 Occupy Cities (计算几何+最短路+有向图最小路径覆盖)
- hdu 4606 Occupy Cities(线段相交+最小路径覆盖+二分)
- 杭电多校联合第一场hdu4606 occupy cities
- hdu 4606 Occupy Cities(几何+二分+KM)
- 计算几何 [二分答案]
- POJ3216 floyd+二分图应用(最小路径覆盖)
- poj 2594 二分图 Floyd闭包+最小路径覆盖
- POJ3216 Repairing Company【二分图最小路径覆盖】【Floyd】
- POJ2594 Treasure Exploration【二分图最小路径覆盖】【Floyd】
- poj3216Repairing Company 二分匹配之最小路径覆盖+floyd
- hdu4606 计算几何+二分+二分图匹配+最短路
- 二分图最小路径覆盖
- PHP中获取目录及子目录下的所有文件路径和目录路径
- What is Linux Driver Model ?
- WPF视频播放
- MFC程序消息处理的顺序
- MFC中OnDraw与OnPaint的区别
- hdu4606 Occupy Cities简单计算几何+floyd+最小路径覆盖+二分答案
- C语言数字类型长度
- python中的深拷贝和浅拷贝理解
- 怎么在外部类的静态方法中创建成员内部类的对象?
- uva 10055 Hashmat the brave warr…
- 488 - Triangle Wave
- UVa 10300 Ecological Premium
- uva 10010 - Where's Waldorf?
- uva 10361 - Automatic Poetry