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 }