http://poj.org/problem?id=3308
给两个定义
最小割:对于图中的两个点(一般为源点和汇点)来说,如果把图中的一些边去掉,如果它们之间无法连通的话,则这些边组成的集合就叫为割了。如果这些边有权值,最小割就是指权值之和最小的一个割。
最大流最小割:应用于网络中,指总流量不超过链路可承载的最大值,且在每条子路径上取尽可能少的流量。对任意一个只有一个源点一个汇点的图来说,从源点到汇点的最大流等于最小割。
之前做二分图的时候看过一篇文章 现在依旧看这篇http://ip96cns.blog.163.com/blog/static/170095192201117465473/
设置超级源点及超级汇点 行和列看做结点 每一个点看做一个边 把行和列两个结点连起来
这个题是求最小乘积 刚开始还以为样例答案错了呢 用一个log函数就可以转换为相加
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<cmath> 7 #include<queue> 8 #define N 2510 9 #define M 400100 10 #define INF 0x3f3f3f3f 11 #define eps 1e-8 12 using namespace std; 13 struct node 14 { 15 int u,v,next; 16 double w; 17 }edge[M]; 18 int head[N],t,vis[N],pp[N],dis[N]; 19 void init() 20 { 21 t=0; 22 memset(head,-1,sizeof(head)); 23 } 24 void add(int u,int v,double w) 25 { 26 edge[t].u = u; 27 edge[t].v = v; 28 edge[t].w = w; 29 edge[t].next = head[u]; 30 head[u] = t++; 31 edge[t].u = v; 32 edge[t].v = u; 33 edge[t].w = 0; 34 edge[t].next = head[v]; 35 head[v] = t++; 36 } 37 int bfs(int e) 38 { 39 int i,u; 40 double w; 41 memset(dis,-1,sizeof(dis)); 42 queue<int>q; 43 q.push(0); 44 dis[0]= 0; 45 while(!q.empty()) 46 { 47 u = q.front(); 48 q.pop(); 49 for(i = head[u] ; i != -1 ; i = edge[i].next) 50 { 51 int v = edge[i].v; 52 w = edge[i].w; 53 if(w>eps&&dis[v]<0) 54 { 55 dis[v] = dis[u]+1; 56 q.push(v); 57 } 58 } 59 } 60 if(dis[e]>0) return 1; 61 return 0; 62 } 63 double dfs(int u,double te,int e) 64 { 65 int i; 66 double s; 67 if(u==e) return te; 68 for(i = head[u] ; i != -1 ; i = edge[i].next) 69 { 70 int v = edge[i].v; 71 double w = edge[i].w; 72 if(w>eps&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w),e))) 73 { 74 edge[i].w-=s; 75 edge[i^1].w+=s; 76 return s; 77 } 78 } 79 return 0; 80 } 81 int main() 82 { 83 int i,n,m,o,k,a,b; 84 double p; 85 cin>>o; 86 while(o--) 87 { 88 cin>>n>>m>>k; 89 init(); 90 for(i = 1; i <= n ; i++) 91 { 92 cin>>p; 93 add(0,i,log(p)); 94 } 95 for(i = 1; i <= m ; i++) 96 { 97 cin>>p; 98 add(n+i,n+m+1,log(p)); 99 } 100 for(i = 1 ; i <= k ; i++) 101 { 102 cin>>a>>b; 103 add(a,n+b,INF); 104 } 105 double s = 0,ss=0; 106 while(bfs(n+m+1)) 107 { 108 ss = dfs(0,INF,n+m+1); 109 if(ss>eps) 110 s+=ss; 111 else break; 112 } 113 114 printf("%.4f ",exp(s)); 115 } 116 return 0; 117 }