POJ3308
2016-08-05 15:33
274 查看
Problem : Paratroopers
Description : 有一个矩阵,里面有一些伞兵,现在每一行都有价格不一样的炮弹,它能打一整行或一整列的目标,现在问你至少要多少花费才能消灭所有的伞兵。
Solution : 最小点权覆盖集。这个题和POJ3041差不多,那个题目也可以用今天这种网络流的方法做,只不过是改一下边的权值就好了(改成1)。伞兵就看成二分图中边。那么从源点到每行连一条边,权值为买这种炮弹的花费,同理,汇点也是一样,然后,把伞兵所在的行与列连边,权值为无穷大。最后跑一遍网络最大流求得最小割也就求得了最小点权和。
Code(C++) :
Description : 有一个矩阵,里面有一些伞兵,现在每一行都有价格不一样的炮弹,它能打一整行或一整列的目标,现在问你至少要多少花费才能消灭所有的伞兵。
Solution : 最小点权覆盖集。这个题和POJ3041差不多,那个题目也可以用今天这种网络流的方法做,只不过是改一下边的权值就好了(改成1)。伞兵就看成二分图中边。那么从源点到每行连一条边,权值为买这种炮弹的花费,同理,汇点也是一样,然后,把伞兵所在的行与列连边,权值为无穷大。最后跑一遍网络最大流求得最小割也就求得了最小点权和。
Code(C++) :
#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> #include <string> #include <queue> #define MIN(a,b) ((a)>(b)? (b):(a)) using namespace std; const int SIZE=20000+50; const double INF=0x3f3f3f3f; struct Node{ int u,v; double cap; Node(){} Node(int U,int V,double Cap): u(U),v(V),cap(Cap){} }; int src,des; vector<int> G[SIZE]; Node e[SIZE*100*4]; int d[SIZE]; int cur[SIZE]; int n; int top; int R,C,M; void addedge(int u,int v,double cap) { G[u].push_back(top); e[top++]=Node(u,v,cap); G[v].push_back(top); e[top++]=Node(v,u,0); } void build() { int i,j; for(i=0;i<SIZE;i++) G[i].clear(); top=0; scanf("%d%d%d",&R,&C,&M); n=R+C; src=0< 4000 /span>; des=n+1; double tmp; for(i=1;i<=R;i++) scanf("%lf",&tmp), addedge(src,i,log(tmp)); for(i=1;i<=C;i++) scanf("%lf",&tmp), addedge(i+R,des,log(tmp)); int x,y; for(i=1;i<=M;i++) scanf("%d%d",&x,&y), addedge(x,y+R,INF); } bool bfs(int src,int des) { memset(d,-1,sizeof(d)); queue<int> que; que.push(src); d[src]=0; while(!que.empty()){ int now=que.front(); que.pop(); for(int i=0;i<G[now].size();i++){ Node &tmp=e[G[now].at(i)]; if(tmp.cap>0&&d[tmp.v]==-1) d[tmp.v]=d[now]+1, que.push(tmp.v); } } return d[des]>=0; } double dfs(int t,double sum,int des) { if(t==des||0.0==sum) return sum; double flow=0,f; for(int &i=cur[t];i<G[t].size();i++){ Node &tmp=e[G[t].at(i)]; if(d[tmp.v]==d[t]+1&&(f=dfs(tmp.v,MIN(sum,tmp.cap),des))>0){ tmp.cap-=f; e[G[t].at(i)^1].cap+=f; sum-=f; flow+=f; if(0.0==sum) break; } } return flow; } double DINIC(int src,int des) { double sum=0; while(bfs(src,des)){ memset(cur,0,sizeof(cur)); sum+=dfs(src,INF,des); } return sum; } void work() { build(); printf("%.4f\n",exp(DINIC(src,des))); } int main() { //freopen("in.data","r",stdin); int T; scanf("%d",&T); while(T--) work(); return 0; }
相关文章推荐
- 超过一定行数的label强制在末尾加上一个...展开且可以点击成全文
- [leetcode] 110. Balanced Binary Tree
- xshell传输文件
- 数据挖掘的一些评价标准
- 使用DS3231SN制作数字时钟
- 可以浏览的国外网站(学习和放松)
- 阿里2017校园招聘电话面试总结
- Oracle中有关Group by 中avg();sum();min();max();count();的运用整理(Oracle的执行顺序)
- 《Python基础教程 第2版·修订版》 字典:当索引不好用时(一)
- Retrofit 使用flatmap操作符时处理错误、异常
- Insight mvc:resources cache-period 解析
- Unity Editor中使用AssetBundle里的shader遇到的问题
- HDU-5795-A Simple Nim-博弈(SG函数)打表找规律
- java数据转换error:java.math.BigDecimal cannot be cast to java.lang.Double
- 【ArcGIS for JavaScript】加载地图,并标注点
- android6.0蓝牙配对加入提示音
- KMP算法
- CentOS 安装 jdk
- Hadoop权威指南:MapReduce应用开发
- 读书笔记四