首页 > 其他 > 详细

zoj 3460 二分+二分图匹配

时间:2015-04-09 23:43:08      阅读:347      评论:0      收藏:0      [点我收藏+]

不错的思想

  1 /*
  2 大致题意:
  3 
  4 用n个导弹发射塔攻击m个目标。每个发射架在某个时刻只能为
  5 一颗导弹服务,发射一颗导弹需要准备t1的时间,一颗导弹从发
  6 射到击中目标的时间与目标到发射架的距离有关。每颗导弹发
  7 射完成之后发射架需要t2的时间进入下个发射流程。现在问
  8 最少需要多少时间可以击毁所有m个目标。
  9 
 10 
 11 大致思路:
 12 二分枚举这个最大时间的最小值,每次按照这个枚举的时间构出
 13 二分图,求最大匹配来判定枚举值是否符合要求。
 14 
 15 注意单位,T1要除于60转化成分的
 16 
 17 */
 18 
 19 #include<stdio.h>
 20 #include<string.h>
 21 #include<iostream>
 22 #include<algorithm>
 23 #include<math.h>
 24 #include<vector>
 25 using namespace std;
 26 const double eps=1e-8;
 27 const int MAXN=2550;
 28 int linker[MAXN];
 29 bool used[MAXN];
 30 vector<int>g[60];
 31 int uN;
 32 bool dfs(int u)
 33 {
 34     for(int i=0;i<g[u].size();i++)
 35     {
 36         if(!used[g[u][i]])
 37         {
 38             used[g[u][i]]=true;
 39             if(linker[g[u][i]]==-1||dfs(linker[g[u][i]]))
 40             {
 41                 linker[g[u][i]]=u;
 42                 return true;
 43             }
 44         }
 45     }
 46     return false;
 47 }
 48 int hungary()
 49 {
 50     int u;
 51     int res=0;
 52     memset(linker,-1,sizeof(linker));
 53     for(u=0;u<uN;u++)
 54     {
 55         memset(used,false,sizeof(used));
 56         if(dfs(u))res++;
 57     }
 58     return res;
 59 }
 60 
 61 int N,M;
 62 double  T1,T2,V;
 63 struct Node
 64 {
 65     int x,y;
 66 };
 67 Node node1[60],node2[60];
 68 double d[60][60];
 69 double tt[MAXN][60];
 70 
 71 double dis(Node a,Node b)
 72 {
 73     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 74 }
 75 
 76 void init()
 77 {
 78     for(int i=0;i<N;i++)
 79       for(int j=0;j<M;j++)
 80         d[i][j]=dis(node1[i],node2[j]);
 81     for(int k=0;k<M;k++)
 82       for(int i=0;i<N;i++)
 83         for(int j=0;j<M;j++)
 84         {
 85             tt[i*M+k][j]=k*T2+(k+1)*T1+d[i][j]/V;
 86         }
 87     uN=M;
 88 }
 89 
 90 double solve()
 91 {
 92     double l=0;
 93     double r=200000000000.0;
 94     double mid;
 95     while(r-l>=eps)
 96     {
 97         mid=(l+r)/2;
 98         for(int i=0;i<M;i++)g[i].clear();
 99         for(int i=0;i<M*N;i++)
100           for(int j=0;j<M;j++)
101           {
102               if(tt[i][j]<=mid)g[j].push_back(i);
103           }
104         if(hungary()==M)
105         {
106            r=mid;
107         }
108         else l=mid;
109     }
110     printf("%.6lf\n",r);
111 }
112 int main()
113 {
114     //freopen("in.txt","r",stdin);
115     //freopen("out.txt","w",stdout);
116     while(scanf("%d%d%lf%lf%lf",&N,&M,&T1,&T2,&V)!=EOF)
117     {
118         T1/=60;//这个注意,没有除一直得不到答案,纠结
119         for(int i=0;i<M;i++)scanf("%d%d",&node2[i].x,&node2[i].y);
120         for(int i=0;i<N;i++)scanf("%d%d",&node1[i].x,&node1[i].y);
121         init();
122         solve();
123     }
124     return 0;
125 }

 

zoj 3460 二分+二分图匹配

原文:http://www.cnblogs.com/cnblogs321114287/p/4412843.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!