hdu 4606 简单计算几何+floyd+最小路径覆盖
思路:将所有的直线的两个端点和城市混在一起,将能直接到达的两个点连线,求一次floyd最短路径。二分枚举bag容量,然后按给的要先后占领的城市由前向后,把能到一步到达的建一条边。然后求一次最小路径覆盖,就是最少需要多少个士兵才能全部占领,跟给出的p值进行比较。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define Maxn 510
#define Maxm Maxn*Maxn
#define eps 1e-6
#define inf 100000000
using namespace std;
int match[Maxn],vi[Maxn],graphic[Maxn][Maxn],n,m,p,list[Maxn];
double dis[Maxn][Maxn];
struct Point{
double x,y;
}city[Maxn*];
struct Edge{
Point a,b;
}edge[Maxn];
void init()
{
int i,j;
memset(vi,,sizeof(vi));
memset(match,-,sizeof(match));
memset(graphic,,sizeof(graphic));
for(i=;i<=;i++)
for(j=;j<=;j++)
dis[i][j]=inf;
}
double multi(Point p0, Point p1, Point p2)//j计算差乘
{ 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 is_cross(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 dfs(int u)
{
int i,j;
for(i=;i<=n;i++)
{
if(!vi[i]&&graphic[u][i])
{
vi[i]=;
if(match[i]==-||dfs(match[i]))
{
match[i]=u;
return ;
}
}
}
return ;
}
int maxmatch()
{
int i,j;
int ans=;
memset(match,-,sizeof(match));
for(i=;i<=n;i++)
{
memset(vi,,sizeof(vi));
if(dfs(i))
ans++;
}
return n-ans;
}
int main()
{
int t,i,j,e,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&p);
init();
for(i=;i<=n;i++)
scanf("%lf %lf",&city[i].x,&city[i].y);
e=n;
for(i=;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[++e].x=edge[i].a.x,city[e].y=edge[i].a.y;city[++e].x=edge[i].b.x,city[e].y=edge[i].b.y;
}
for(i=;i<=n;i++)
scanf("%d",list+i);
int flag=;
for(i=;i<e;i++)//将能直线到达的点建边
{
for(j=i+;j<=e;j++)
{
flag=;
for(k=;k<=m;k++)
{
if(is_cross(city[i],city[j],edge[k].a,edge[k].b))
{
flag=;
break;
}
}
if(!flag)
dis[i][j]=dis[j][i]=Dis(city[i],city[j]);
}
}
double Max=;
for(k=;k<=e;k++)//求所有点的最短路径
for(i=;i<=e;i++)
for(j=;j<=e;j++)
{
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
for(i=;i<=n;i++)
for(j=;j<=n;j++)
if(dis[i][j]!=inf)
Max=max(Max,dis[i][j]);
double l,r,mid;
l=,r=Max;
int temp;
while(r-l>eps)//二分枚举bag容量
{
mid=(l+r)/;
memset(graphic,,sizeof(graphic));
for(i=;i<n;i++)
for(j=i+;j<=n;j++)
{
if(dis[list[i]][list[j]]<=mid)
{
graphic[list[i]][list[j]]=;
}
}
temp=maxmatch();
if(temp>p)
l=mid;
else
r=mid;
}
printf("%.2lf\n",r);
}
return ;
}
hdu 4606 简单计算几何+floyd+最小路径覆盖的更多相关文章
- HDU 6311 Cover (无向图最小路径覆盖)
HDU 6311 Cover (无向图最小路径覆盖) Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)
题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...
- hdu 1151 Air Raid(二分图最小路径覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=1151 Air Raid Time Limit: 1000MS Memory Limit: 10000K To ...
- HDU 1151 Air Raid(最小路径覆盖)
题目大意: 有n个城市,m条道路,城市的道路是单向. 现在我们的伞兵要降落在城市里,然后我门的伞兵要搜索所有道路.问我们最少占领多少个城市就可以搜索所有的道路了. 我们可以沿着道路向前走到达另一个城 ...
- POJ 2594 Treasure Exploration (Floyd+最小路径覆盖)
<题目链接> 题目大意: 机器人探索宝藏,有N个点,M条边.问你要几个机器人才能遍历所有的点. 解题分析: 刚开始还以为是最小路径覆盖的模板题,但是后面才知道,本题允许一个点经过多次,这与 ...
- Treasure Exploration---poj2594(传递闭包Floyd+最小路径覆盖)
题目链接:http://poj.org/problem?id=2594 在外星上有n个点需要机器人去探险,有m条单向路径.问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过(这就是和单 ...
- POJ2594:Treasure Exploration(Floyd + 最小路径覆盖)
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 9794 Accepted: 3 ...
- POJ-2594 Treasure Exploration,floyd+最小路径覆盖!
Treasure Exploration 复见此题,时隔久远,已忘,悲矣! 题意:用最少的机器人沿单向边走完( ...
- HDU - 1151 Air Raid (最小路径覆盖)
题意:给定一个有向无环图,求最少划分几条路径,使之能够覆盖所有点. 分析:这可以转化为DAG上的最小路径覆盖问题. 路径覆盖的定义:有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且 ...
随机推荐
- HDU 5794 A Simple Chess (容斥+DP+Lucas)
A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...
- CentOS查看系统信息-CentOS查看命令
一:查看cpu more /proc/cpuinfo | grep "model name" grep "model name" /proc/cpuinfo 如 ...
- listview禁止双击一条之后选中复选框按钮的方法
this.listViewUsers.SelectedItems[0].Checked = !this.listViewUsers.SelectedItems[0].Checked;
- UVaLive 7360 Run Step (排列组合,枚举)
题意:给定一个数 n ,表示一共有 n 步,然后你可以迈一步也可以迈两步,但是左腿和右腿的一步和两步数要一样,并且两步数不小于一步数,问你有多少种方式. 析:虽然是排列组合,但还是不会做.....水啊 ...
- HTML5学习笔记(一):HTML简介
Web前端涵盖的内容较多且杂,主要由3个部分组成:HTML标记语言.CSS样式语言和JavaScript脚本语言组成,而下面我们将先学习最新的标记语言HTML5. <!DOCTYPE>标记 ...
- const修饰的双重指针赋值解惑
在c程序中,我们可能经常会使用到指针之间的赋值. 传统的赋值操作: char *cp = "c"; const char *ccp; ccp = cp; printf(" ...
- 教你50招提升ASP.NET性能(十七):不要认为问题只会从业务层产生
(28)Don’t assume that problems can only arise from business logic 招数28: 不要认为问题只会从业务层产生 When beginnin ...
- Android 监听屏幕锁屏,用户解锁
在做一个程序的时候,需要时刻保持某一服务是启动的,因此想到了通过监听屏幕SCREEN_ON和SCREEN_OFF这两个action.奇怪的是,这两个action只能通过代码的形式注册,才能被监听到,使 ...
- Codeforces Round #185 (Div. 2) B. Archer 水题
B. Archer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/312/problem/B D ...
- utf-8 和gbk编码的差别
UTF- 8: 是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码. GBK 是国家标准GB2312基础上扩容后兼容GB2312的标准. GBK的文 ...