POJ 3380 最大流

Paratroopers

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status Practice POJ
3308

Appoint description: 
System Crawler  (2014-10-14)

Description

It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the Mars. Recently, the commanders of the Earth are informed by their spies that the invaders of Mars want to land some paratroopers in the × n grid
yard of one their main weapon factories in order to destroy it. In addition, the spies informed them the row and column of the places in the yard in which each paratrooper will land. Since the paratroopers are very strong and well-organized, even one of them,
if survived, can complete the mission and destroy the whole factory. As a result, the defense force of the Earth must kill all of them simultaneously after their landing.

In order to accomplish this task, the defense force wants to utilize some of their most hi-tech laser guns. They can install a gun on a row (resp. column) and by firing this gun all paratroopers landed in this row (resp. column) will die. The cost of installing
a gun in the ith row (resp. column) of the grid yard is ri (resp. ci ) and the total cost of constructing a system firing all guns simultaneously is equal to the product of their costs. Now, your team as a high
rank defense group must select the guns that can kill all paratroopers and yield minimum total cost of constructing the firing system.

Input

Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing three integers 1 ≤ m ≤ 50 , 1 ≤ n ≤ 50 and 1 ≤ l ≤ 500 showing the number
of rows and columns of the yard and the number of paratroopers respectively. After that, a line with m positive real numbers greater or equal to 1.0 comes where the ith number is ri and then, a line with npositive
real numbers greater or equal to 1.0 comes where the ith number is ci. Finally, l lines come each containing the row and column of a paratrooper.

Output

For each test case, your program must output the minimum total cost of constructing the firing system rounded to four digits after the fraction point.

Sample Input

1
4 4 5
2.0 7.0 5.0 2.0
1.5 2.0 2.0 8.0
1 1
2 2
3 3
4 4
1 4

Sample Output

16.0000

题意:给出火星人降落的坐标(行x,列y)和使用每一行每一列武器的代价,你可以在一行或一列使用一把武器,可以消灭掉该行或该列的所有外星人。使用多种武器的代价是他们的乘积,你需要求出消灭所有火星人的最小代价。

思路:在把乘机转化成对数相加的形式,可以看到要消灭一个外星人,要么在他所在的行上放一把武器,要么在他所在列上放一把武器,因此可以在源点s和行x上连一条log(w)的边,在列和汇点t上连一条log(w)的边,在外星人的坐标x和y+n之间连一条INF的边。因为增广的时候满足流量限制所以会选择最小的代价。

不过还是wa了很久。。原因就是用个g++提交,输出的时候使用了%lf,后来改成%f了还是wa,后来发现关闭了c++和c的输入输出同步,但任然在混用输入。。取消关闭之后就ac了。。。所以建议没事还是不要混用输入输出了

代码如下:

/*************************************************************************
    > File Name: c.cpp
    > Author: acvcla
    > QQ:
    > Mail: [email protected]
    > Created Time: 2014年10月13日 星期一 22时26分17秒
 ************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 5e2 + 30;
const int INF =1e7;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
int n,m,s,t,l;
int d[maxn],cur[maxn];
struct  Edge
{
	int from,to;
	double cap,flow;
};
std::vector<int>G[maxn];
std::vector<Edge>edges;
void init(int n){
	for(int i=0;i<=n;i++)G[i].clear();
	edges.clear();
}
void addEdge(int u,int v,double w)
{
	edges.pb((Edge){u,v,w,0});
	edges.pb((Edge){v,u,0.0,0});
	int sz=edges.size();
	G[u].pb(sz-2);
	G[v].pb(sz-1);
}
int bfs(){
	memset(d,0,sizeof d);
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<G[u].size();i++){
			Edge &e=edges[G[u][i]];
			if(e.to==s)continue;
			if(!d[e.to]&&e.cap>e.flow){
				q.push(e.to);
				d[e.to]=d[u]+1;
			}
		}
	}
	return d[t];
}
double dfs(int u,double a)
{
	if(u==t||a==0.0)return a;
	double flow=0.0,f=0.0;
	for(int &i=cur[u];i<G[u].size();++i){
		Edge &e=edges[G[u][i]];
		if(d[e.to]==d[u]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0.0){
			e.flow+=f;
			edges[G[u][i]^1].flow-=f;
			flow+=f;
			a-=f;
			if(a==0.0)break;
		}
	}
	return flow;
}
double Dinic(){
	double flow=0;
	while(bfs()){
		memset(cur,0,sizeof cur);
		flow+=dfs(s,INF);
	}
	return flow;
}
int main(){
                //开启关闭同步且混用输入输出wa,注释掉AC
		//ios_base::sync_with_stdio(false);
		//cin.tie(0);
		int T;scanf("%d",&T);
		while(T--){
			scanf("%d%d%d",&n,&m,&l);
			int u,v;
			s=0,t=n+1+m;
			init(t);
			double w;
			for(int i=1;i<=n;i++){
				cin>>w;
				addEdge(s,i,log(w));
			}for(int i=1;i<=m;i++){
				cin>>w;
				addEdge(n+i,t,log(w));
			}
			for(int i=1;i<=l;i++){
				cin>>u>>v;
				addEdge(u,v+n,INF);
			}
			double ans=Dinic();
			printf("%.4f\n",exp(ans));
		}
		return 0;
}
时间: 2024-10-13 21:57:28

POJ 3380 最大流的相关文章

poj 3281 最大流+建图

很巧妙的思想 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/21/2649850.html 本题能够想到用最大流做,那真的是太绝了.建模的方法很妙! 题意就是有N头牛,F个食物,D个饮料. N头牛每头牛有一定的喜好,只喜欢几个食物和饮料. 每个食物和饮料只能给一头牛.一头牛只能得到一个食物和饮料. 而且一头牛必须同时获得一个食物和一个饮料才能满足.问至多有多少头牛可以获得满足. 最初相当的是二分匹配.但是明显不行,因为要分配两个东西,两个东

UVA 820 --- POJ 1273 最大流

找了好久这两个的区别...UVA820 WA了 好多次.不过以后就做模板了,可以求任意两点之间的最大流. UVA 是无向图,因此可能有重边,POJ 1273是有向图,而且是单源点求最大流,因此改模板的时候注意一下. 而且我居然犯了更愚蠢的错误,以为重边的时候需要选最大的,正解应该是累加.... 1 #include<stdio.h> 2 #include<queue> 3 #include<string.h> 4 #define INF 999999 5 using n

POJ 2289 最大流

Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 7624   Accepted: 2562 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list in her cell phone. The con

poj 3498 最大流

March of the Penguins Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 4809   Accepted: 2195 Description Somewhere near the south pole, a number of penguins are standing on a number of ice floes. Being social animals, the penguins would l

POJ 3204 最大流

题意:问加哪些边容量增大能够增加整体流量. 很显然,增加单个边容量改变全局容量,一遍最大流之后,这些边只有可能出现在满流的边内,而且是一条路中唯一的一条满流边. 题解: 大众解法,一遍最大流之后,整个图跑残了,记录那些满流的边,从起点开始深搜,只走非满流边,从终点开始搜,只走非满流边,如果某条满流边起始点被起点标记,且终止点被终点标记,那么这条满流边存在于有且仅有他自己的从起点到终点的非满流路线中.这条边为关键边,Num++; 我的做法:既然一遍最大流之后 ,整个图跑残了,如果将某些关键边进行添

POJ 2112 最大流+二分+(建图:最重要的)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12521   Accepted: 4524 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) co

[poj 3436]最大流+输出结果每条边流量

题目链接:http://poj.org/problem?id=3436 大力套kuangbin板过了orz #include<cstdio> #include<cstring> using namespace std; const int MAXN = 210; const int MAXM = 40010; const int INF = 0x3f3f3f3f; struct Edge { int to,next,cap,flow; } edge[MAXM]; int tol;

POJ 1087 最大流裸题 + map

A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15597   Accepted: 5308 Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an int

[转载 ]POJ 1273 最大流模板

转载 百度文库花了5分下的 不过确实是自己需要的东西经典的最大流题POJ1273 ——其他练习题 POJ3436 . 题意描述: 现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条水渠,给出这n条水渠所连接的池塘和所能流过的水量,求水渠中所能流过的水的最大容量.一道基础的最大流题目.但是模板小心使用,目前只是求单源点的最大流. 参考数据: 输入: 5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10 输出: 50 程序实现: 增广路算法Edmonds_Karp