伞兵(Paratroopers)
Posted kakakakakaka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了伞兵(Paratroopers)相关的知识,希望对你有一定的参考价值。
伞兵(Paratroopers)
时间限制: 1 Sec 内存限制: 128 MB题目描述
公元 2500 年,地球和火星之间爆发了一场战争。最近,地球军队指挥官获悉火星入侵者将派一些伞兵来摧毁地球的兵工厂,兵工厂是一个 m×n 大小的网格。他还获悉每个伞兵将着陆的具体位置(行和列)。由于火星的伞兵个个都很强壮、而且组织性强,只要有一个伞兵存活了,就能摧毁整个兵工厂。因此,地球军队必须在伞兵着陆后瞬间全部杀死他们。
为了完成这个任务,地球军队需要利用高科技激光枪。他们能在某行(或某列)安装一架激光枪,一架激光枪能杀死该行(或该列)所有的伞兵。在第 i 行安装一架激光枪的费用是 Ri,在第 i 列安装的费用是 Ci。要安装整个激光枪系统,以便能同时开火,总的费用为这些激光枪费用的乘积。现在,你的任务是选择能杀死所有伞兵的激光枪,并使得整个系统的费用最小。
输入
输入文件的第 1 行为整数 T,表示测试数据的数目,接下来有 T 个测试数据。每个测试数据的第 1 行为 3 个整数 m、n 和 L,1≤m≤50,1≤n≤50,1≤L≤500,分别表示网格的行和列、以及伞兵的数目;接下来一行为 m 个大于或等于 1.0 的实数,第 i 个实数表示 Ri;再接下来一行为 n 个大于或等于 1.0 的实数,第 i 个实数表示 Ci;最后 L 行,每行为两个整数,描述了每个伞兵的着陆位置。
输出
对每个测试数据,输出搭建整个激光枪系统的最小费用,精确到小数点后面 4 位有效数字。
样例输入
样例输出
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> #include<queue> #include<stack> #include<ctime> #include<vector> using namespace std; int n,m,l,t; struct node { int next,to; double cap; }edge[50001]; int size=1,head[501]; void putin(int from,int to,double cap) { size++; edge[size].to=to; edge[size].cap=cap; edge[size].next=head[from]; head[from]=size; } void in(int from,int to,double cap) { putin(from,to,cap); putin(to,from,0); } int dist[501],numbs[501]; void bfs(int src,int des) { int i; memset(dist,0,sizeof(dist)); memset(numbs,0,sizeof(numbs)); queue<int>mem; mem.push(des); dist[des]=0;numbs[0]++; while(!mem.empty()) { int x=mem.front();mem.pop(); for(i=head[x];i!=-1;i=edge[i].next) { int y=edge[i].to; if(edge[i].cap==0&&dist[y]==0&&y!=des) { dist[y]=dist[x]+1; numbs[dist[y]]++; mem.push(y); } } } return; } double dfs(int src,double flow,int des) { if(src==des)return flow; int i,mindist=n+m+2; double low=0; for(i=head[src];i!=-1;i=edge[i].next) { int y=edge[i].to; if(edge[i].cap) { if(dist[y]==dist[src]-1) { double t=dfs(y,min(flow-low,edge[i].cap),des); edge[i].cap-=t; edge[i^1].cap+=t; low+=t; if(dist[src]>=n+m+2)return low; if(flow==low)break; } mindist=min(mindist,dist[y]+1); } } if(!low) { if(!(--numbs[dist[src]]))dist[n+m+2]=n+m+2; ++numbs[dist[src]=mindist]; } return low; } double ISAP(int src,int des) { double ans=0; bfs(src,des); while(dist[0]<n+m+2)ans+=dfs(src,2e8,des); return ans; } int main() { int i,j; scanf("%d",&t); while(t--) { size=1; memset(head,-1,sizeof(head)); scanf("%d%d%d",&n,&m,&l); for(i=1;i<=n;i++) { double q; scanf("%lf",&q); in(0,i,log(q)); } for(i=1;i<=m;i++) { double q; scanf("%lf",&q); in(n+i,n+m+1,log(q)); } for(i=1;i<=l;i++) { int from,to; scanf("%d%d",&from,&to); in(from,n+to,100000000); } double maxflow=ISAP(0,n+m+1); printf("%.4lf\n",exp(maxflow)); } return 0; }
以上是关于伞兵(Paratroopers)的主要内容,如果未能解决你的问题,请参考以下文章
POJ3308 Paratroopers(网络流)(最小割)