网络流 poj 3308 最小割
t个样例
n*m的矩阵 L个伞兵
给出每行每列装激光的花费
伞兵的位置
要求杀死所有伞兵 总费用为这些费用的乘积 求花费最小
建图 源点 -> 行 -> 列 -> 汇点
权 花费 inf 花费
花费相乘等于 log(花费)相加 都变成double 最后取e
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 #include<math.h> 6 7 using namespace std; 8 9 int S,T,cnt; 10 #define inf 100000000 11 #define MAXN 2000 12 #define MAXN1 3500 13 int head[MAXN+10]; 14 int vis[MAXN+10]; 15 16 struct edg 17 { 18 int to,next; 19 double w; 20 }x[MAXN1*2]; 21 22 void add(int u,int v,double w) 23 { 24 x[cnt].next=head[u]; 25 x[cnt].to=v; 26 x[cnt].w=w; 27 head[u]=cnt++; 28 } 29 int bfs() 30 { 31 queue<int>q1; 32 memset(vis,-1,sizeof(vis)); 33 vis[S]=0; 34 q1.push(S); 35 36 while(!q1.empty()) 37 { 38 int now=q1.front(); 39 q1.pop(); 40 int j; 41 42 for(j=head[now];j!=-1;j=x[j].next) 43 { 44 if(vis[x[j].to]<0&&x[j].w>0) 45 { 46 vis[x[j].to]=vis[now]+1; 47 q1.push(x[j].to); 48 } 49 } 50 } 51 return vis[T]!=-1; 52 53 } 54 double dfs(int u,double w) 55 { 56 double ans=0; 57 if(u==T) 58 return w; 59 int j; 60 for(j=head[u];j!=-1;j=x[j].next) 61 { 62 if(vis[x[j].to]==vis[u]+1&&x[j].w>0) 63 { 64 double b=dfs(x[j].to,min(w-ans,x[j].w)); 65 x[j].w-=b; 66 x[j^1].w+=b; 67 ans+=b; 68 } 69 } 70 return ans; 71 } 72 73 int main() 74 { 75 int t; 76 scanf("%d",&t); 77 78 while(t--) 79 { 80 int n,m,l,i; 81 scanf("%d%d%d",&n,&m,&l); 82 S=0,T=n+m+1; 83 cnt=0; 84 memset(head,-1,sizeof(head)); 85 for(i=1;i<=n;i++) 86 { 87 double a; 88 scanf("%lf",&a); 89 add(S,i,log(a)),add(i,S,0); 90 } 91 for(i=1;i<=m;i++) 92 { 93 double a; 94 scanf("%lf",&a); 95 add(i+n,T,log(a)),add(T,i+n,0); 96 } 97 98 for(i=1;i<=l;i++) 99 { 100 int a,b; 101 scanf("%d%d",&a,&b); 102 add(a,b+n,inf); 103 add(b+n,a,0); 104 } 105 double ans=0; 106 while(bfs()) 107 ans+=dfs(S,inf); 108 109 printf("%.4lf\n",exp(ans)); 110 } 111 return 0; 112 }
posted on 2016-11-11 15:53 HelloWorld!--By-MJY 阅读(170) 评论(0) 编辑 收藏 举报