zoj 3460 二分+二分图匹配

不错的思想

  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 }

 

你可能感兴趣的:(二分图)