Occupy Cities

hdu4606:http://acm.hdu.edu.cn/showproblem.php?pid=4606

题意:在一个二维坐标系中,有n个城市,坐标给出来了,然后有p个士兵要去占领这n个城市,但是路上有m个路障,都是线段,士兵不能越过路障前进。

每个士兵都有相同容量大小的一个干粮袋,每到一个城市他就能补充满自己的干粮袋。中途走路时走一个单位长度就消耗一个单位的干粮。

现在问的是这些个干粮袋最小的容量是多少,前提是保证p个士兵能占领完这n个城市,城市被占领顺序也是题目给好的,必须遵守。

题解:这一题是一道很好的综合题。首先一点,就是求出任意两个城市的最短距离。这个也是我今天学到的知识。我们可以把障碍的端点当做2个点,如果城市i和城市j之间没有障碍的话,那么i,j之间的距离就可以直接算出。如果有障碍的话,就只能绕过障碍的端点来求。怎么求呢?只要把端点当做路径上的点就可以了,然后用floyd过一遍即可。这里,要用到判断两条线段是否相交的。然后可以联想到的是最小点覆盖。但是这里的是最小点覆盖小于p都是满足的。所以接下来可以二分枚举长度,找到最小额满足条件的长度。用到二分以及二分图的最大匹配。因为最小点覆盖==点数--二分图的最大匹配。还有一个就序列,这也是要考虑。这里只哎哟我们建图的时候,让前面的序列指向后面的序列就可以了。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cmath>
  6 using namespace std;
  7 const double inf=1000000000.0;
  8 int n,m,p;
  9 int seq[600],cy[600];
 10 double g[600][600];
 11 bool key[600][600],visit[600];
 12 struct point{
 13    double x,y;
 14 }dian[602];
 15 struct Node{
 16     point a;
 17     point b;
 18 }xian[602];
 19 double dis(int a,int b){
 20   return  sqrt((dian[a].x-dian[b].x)*(dian[a].x-dian[b].x)+(dian[a].y-dian[b].y)*(dian[a].y-dian[b].y));
 21
 22 }
 23 double Cross( point a,  point b,  point  o){
 24     return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
 25 }
 26 bool IsIntersect( Node u, Node v){
 27     return (Cross(v.a, u.b, u.a) * Cross(u.b, v.b, u.a) > 0) &&
 28            (Cross(u.a, v.b, v.a) * Cross(v.b, u.b, v.a) > 0) &&
 29            (max(u.a.x, u.b.x) > min(v.a.x, v.b.x)) &&
 30            (max(v.a.x, v.b.x) > min(u.a.x, u.b.x)) &&
 31            (max(u.a.y, u.b.y) > min(v.a.y, v.b.y)) &&
 32            (max(v.a.y, v.b.y) > min(u.a.y, u.b.y));
 33 }
 34
 35 bool judge(int a,int b){
 36     for(int i=1;i<=m;i++){
 37         if((a+1-n)/2==i&&(b+1-n)/2==i)continue;
 38         Node temp;temp.a=dian[a];temp.b=dian[b];
 39         if(IsIntersect(temp,xian[i]))
 40             return false;
 41     }
 42   return true;
 43 }
 44 int path(int u){
 45      for(int i=1;i<=n;i++){
 46         if(!visit[i]&&key[u][i]){
 47             visit[i]=1;
 48         if(cy[i]==-1||path(cy[i])){
 49             cy[i]=u;
 50             return 1;
 51         }
 52        }
 53      }
 54    return 0;
 55 }
 56 int maxmatch(){
 57     memset(cy,-1,sizeof(cy));
 58     int res=0;
 59     for(int i=1;i<=n;i++){
 60     memset(visit,0,sizeof(visit));
 61         res+=path(i);
 62     }
 63     return res;
 64 }
 65 bool task(double mid){
 66     memset(key,0,sizeof(key));
 67     for(int i=1;i<=n;i++)
 68        for(int j=1;j<=n;j++){
 69         if(g[i][j]<=mid&&seq[i]<seq[j])
 70             key[i][j]=1;
 71     }
 72     int as=maxmatch();
 73     if(n-as<=p)return true;
 74     else return false;
 75 }
 76
 77 double solve(){
 78      double l=0,r=inf,ans=0;
 79      while(abs(l-r)>0.0000001){
 80         double mid=(l+r)/2;
 81         if(task(mid)){
 82             ans=mid;
 83             r=mid;
 84         }
 85         else
 86             l=mid;
 87      }
 88      return ans;
 89 }
 90 int temp;
 91 int main(){
 92     int cas;
 93     scanf("%d",&cas);
 94     while(cas--){
 95         scanf("%d%d%d",&n,&m,&p);
 96         memset(g,0,sizeof(g));
 97        for(int i=1;i<=n;i++){
 98           scanf("%lf%lf",&dian[i].x,&dian[i].y);
 99        }
100        for(int i=1;i<=m;i++){
101         scanf("%lf %lf",&xian[i].a.x,&xian[i].a.y);
102          dian[i*2+n-1].x=xian[i].a.x;
103          dian[i*2+n-1].y=xian[i].a.y;
104         scanf("%lf %lf",&xian[i].b.x,&xian[i].b.y);
105          dian[i*2+n].x=xian[i].b.x;
106          dian[i*2+n].y=xian[i].b.y;
107        }
108        memset(seq,0,sizeof(seq));
109       for(int i=1;i<=n;i++){
110           scanf("%d",&temp);
111           seq[temp]=i;
112       }
113        for(int i=1;i<=n+2*m;i++){
114           for(int j=1;j<=n+2*m;j++){
115               if(j==i)continue;
116               if(judge(i,j)){
117                 g[i][j]=dis(i,j);
118               }
119               else
120                 g[i][j]=inf;
121           }
122           g[i][i]=inf;
123        }
124        for(int k=1;k<=n+2*m;k++)
125            for(int i=1;i<=n+2*m;i++)
126               for(int j=1;j<=n+2*m;j++)
127                  g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
128           double ans=0;
129           ans=solve();
130       printf("%.2f\n",ans);
131     }
132 }

Occupy Cities,布布扣,bubuko.com

时间: 2024-10-14 20:53:27

Occupy Cities的相关文章

hdu 4606 Occupy Cities(线段相交+最小路径覆盖+二分)

Occupy Cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1178    Accepted Submission(s): 388 Problem Description The Star Wars is coming to an end as the Apple Planet is beaten by the Ban

hdu-2874 Connections between cities(lca+tarjan+并查集)

题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, s

HDU 3371 kruscal/prim求最小生成树 Connect the Cities 大坑大坑

这个时间短 700多s #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; struct node{ int u; int v; int w; }que[100000]; int father[505]; bool cmp(struct node a,struct node b){ return a.w<b.w;

hdu 3371 Connect the Cities

链接:hdu 3371 已知已连通的路的序号,以及未连通的路的费用,求将所有城市连通的最小费用 也是将已连通的路的费用记为0,就转化成了基本最小生成树的题 不过这题数组要开的大点,不然很容易就RE了... #include<cstdio> #include<algorithm> using namespace std; int f[510],n,m; struct stu { int a,b,c; }t[100000]; int cmp(struct stu x,struct st

1013. Battle Over Cities (25)

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of

Connect the Cities(prim)用prim都可能超时,交了20几发卡时过的

Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 701 Accepted Submission(s): 212   Problem Description In 2100, since the sea level rise, most of the cities disappear. Though som

codeforces 613D:Kingdom and its Cities

Description Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in order not to lose face in front of the relatives, the King should first finish reforms in his kingdom. As the King can not wait for his daug

HDU 3371 Connect the Cities 【最小生成树,Prime算法+Kruskal算法】

Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17167    Accepted Submission(s): 4335 Problem Description In 2100, since the sea level rise, most of the cities disappear. Tho

hdu 5148 Cities(树形dp)

题目链接:hdu 5148 Cities dp[i][j]表示以i为根节点,选j个最优值,每条边被选中的时候就计算出被经过的次数,并乘上权值. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; typedef pair<int, int> pii; typedef long long ll; const