pku 3308 Paratroopers
2010-10-06 16:50
218 查看
这是一道最小点覆盖问题,以前也做过类似的,但那道题没有权值,做法是点数减去二分图匹配数(如果构图时重复计算了,二分匹配数别忘了除2)。而这道题有权值,方法是加入超级源点和超级汇点,源点和所有行节点相连,所有列节点和汇点相连,权值为行或列的花费,如果a行b列有敌人,则把节点a和节点b相连,权值为无穷大。现在求源点和汇点之间的最小割,即最大流。
还有一个需要注意的地方是,这里问题是要求cost的乘积,可以通过使用log()把乘法先转换为加法,最后输出的时候再用exp()转换回去。
这道题还有几个地方把我恶心了,一是在精度控制上(cap[u][v]>flow[u][v]+1E-8),二是再g++中用printf时参数为lf有问题,要用f,vc++没有这个问题。
还有一个需要注意的地方是,这里问题是要求cost的乘积,可以通过使用log()把乘法先转换为加法,最后输出的时候再用exp()转换回去。
这道题还有几个地方把我恶心了,一是在精度控制上(cap[u][v]>flow[u][v]+1E-8),二是再g++中用printf时参数为lf有问题,要用f,vc++没有这个问题。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define HEAD 110 #define inf 100000000.0 using namespace std; double cap[HEAD][HEAD],flow[HEAD][HEAD],a[HEAD]; int p[HEAD],q[10000],front,rear; void Init() { memset(cap,0,sizeof(cap)); memset(flow,0,sizeof(flow)); } double Edmonds(int s,int t,int n) { double f=0; while(1) { memset(a,0,sizeof(a)); a[s]=inf; front=rear=0; q[++rear]=s; while(front!=rear) { int u=q[++front]; for(int v=0;v<n;++v) if((!a[v])&&cap[u][v]>flow[u][v]+1E-8) { p[v]=u; q[++rear]=v; a[v]=min(a[u],cap[u][v]-flow[u][v]); } } if(fabs(a[t])<1E-8) break; for(int u=t;u!=s;u=p[u]) { flow[p[u]][u]+=a[t]; flow[u][p[u]]-=a[t]; } f+=a[t]; } return f; } int main(void) { int row,col,poi,tol,a,b; double res; double temp; scanf("%d",&tol); while(tol--) { Init(); scanf("%d%d%d",&row,&col,&poi); for(int i=1;i<=row;++i) { scanf("%lf",&temp); cap[0][i]=log(temp); } int en=row+col+1; for(int i=row+1;i<=row+col;++i) { scanf("%lf",&temp); cap[i][en]=log(temp); } while(poi--) { scanf("%d%d",&a,&b); cap[a][b+row]=inf; } res=Edmonds(0,en,en+1); printf("%.4f/n",exp(res)); } return 0; }
相关文章推荐
- pku 3308 Paratroopers(带权二分图最小点覆盖)
- pku 3308 Paratroopers 最大流最小割
- POJ 3308 Paratroopers(最小割+Dinic)
- POJ 3308 Paratroopers (最小点权覆盖Dinic)
- poj 3308 Paratroopers最小点权覆盖
- POJ 3308 Paratroopers【最大流】
- POJ 3308 Paratroopers
- POJ 3308 Paratroopers
- poj 3308 Paratroopers
- POJ 3308 Paratroopers
- POJ3308_Paratroopers(最大流最小割)
- POJ 3308 Paratroopers(最小割/KM)
- POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)
- 【POJ】3308 Paratroopers 化乘为加——最小点权覆盖
- 【最小割】POJ-3308 Paratroopers
- (模板题)poj 3308 Paratroopers(Dinic算法最大流)
- poj 3308 Paratroopers 最小割—最大流
- poj 3308 Paratroopers
- POJ 3308 Paratroopers(最小割EK)
- POJ 3308--Paratroopers【 最小点权覆盖 && 最小割】