您的位置:首页 > 运维架构

poj 3308 Paratroopers最小点权覆盖

2016-09-12 23:12 459 查看
//poj 3308
//sep9
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=128;
const int MAXM=10024;
const double MAX=100000.0;
struct Edge
{
int v,nxt;
double f;
}e[MAXM*2+10];
queue<int> que;
int src,sink;
int g[MAXN+10];
int nume;
bool vis[MAXN+10];
int dist[MAXN+10];

double row[MAXN],col[MAXN];

void addedge(int u,int v,double c)
{
e[++nume].v=v;e[nume].f=c;e[nume].nxt=g[u];g[u]=nume;
e[++nume].v=u;e[nume].f=0;e[nume].nxt=g[v];g[v]=nume;
}

void init()
{
memset(g,0,sizeof(g));
nume=1;
}

int bfs()
{
while(!que.empty()) que.pop();
memset(dist,0,sizeof(dist));
memset(vis,0,sizeof(vis));
vis[src]=true;
que.push(src);
while(!que.empty()){
int u=que.front();que.pop();
for(int i=g[u];i;i=e[i].nxt)
if(e[i].f>0&&!vis[e[i].v]){
que.push(e[i].v);
dist[e[i].v]=dist[u]+1;
vis[e[i].v]=true;
if(e[i].v==sink)
return 1;
}
}
return 0;
}

double dfs(int u,double delta)
{
if(u==sink)
return delta;
double ret=0;
for(int i=g[u];ret<delta&&i;i=e[i].nxt)
if(e[i].f>0&&dist[e[i].v]==dist[u]+1){
double dd=dfs(e[i].v,min(e[i].f,delta-ret));
if(dd>0){
e[i].f-=dd;
e[i^1].f+=dd;
ret+=dd;
}
else
dist[e[i].v]=-1;
}
return ret;
}

double dinic()
{
double ret=0;
while(bfs()==1)
ret+=dfs(src,MAX);
return ret;
}

int main()
{
int cases;
scanf("%d",&cases);
while(cases--){
int n,m,l;
scanf("%d%d%d",&n,&m,&l);
for(int i=1;i<=n;++i)
scanf("%lf",&row[i]);
for(int i=1;i<=m;++i)
scanf("%lf",&col[i]);
init();
src=0,sink=n+m+1;
for(int i=1;i<=n;++i)
addedge(src,i,log(row[i]));
for(int i=1;i<=m;++i)
addedge(n+i,sink,log(col[i]));
for(int i=1;i<=l;++i){
int a,b;
scanf("%d%d",&a,&b);
addedge(a,n+b,MAX);
}
double ans=dinic();
printf("%.4lf\n",exp(ans));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 算法