盒子嵌套问题 (二分图||费用流)
来源:互联网 发布:交换机的tftp端口号 编辑:程序博客网 时间:2024/06/06 15:48
题目大意:给定n个盒子,并且有们的长宽,一个盒子可以放到 另一个长宽<=自己长宽的盒子中,求最会的最小占地面积。
思路:法一:可以用二分匹配做,按照面积排序,注意和按照边长排序的区别,然后从大到小进行匹配(因为先要把大的进行匹配之后才匹配小的,否则小的匹配完了之后剩下下对面积大的盒子占地也会多)。
法二:用费用流建图,注意在链接盒子与盒子之间的关系时,费用是负的小盒子的面积这样求出来的是最大的放在大盒子里边的面积。
二分图#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;struct node{ int l,h;}q[201];int mp[201][201];bool op(node a,node b){ return a.l*a.h<b.l*b.h;}int cro[201],n;bool vis[201];bool so(int x){ for(int i = n;i >=1;-- i){ if(mp[x][i]&&!vis[i]){ vis[i] = true; if(cro[i] == -1||so(cro[i])){ cro[i] = x; return true; } } } return false;}int main(){ int m,i,j,k,ans; while(~scanf("%d",&n)){ ans=0; memset(mp,0,sizeof(mp)); for(i = 1;i <= n;++ i){ scanf("%d%d",&q[i].l,&q[i].h); ans += q[i].l*q[i].h; } sort(q+1,q+1+n,op); for(i = 1;i <= n;++i ){ for(j = i+1 ;j <= n;++ j){ if(q[j].l >= q[i].l&&q[j].h >= q[i].h) mp[i][j]=1; } } memset(cro,-1,sizeof(cro)); for(i = n;i >=1;-- i){ memset(vis,false,sizeof(vis)); if(so(i)) ans -= q[i].l*q[i].h; } printf("%d\n",ans); } return 0;}
费用流:#include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define LL long long#define inf 0x3f3f3f3f#define eps 1e-8#define ls l,mid,rt<<1#define rs mid+1,r,rt<<1|1const double PI=acos(-1.0);using namespace std;struct node{ int to,w,c,next;}q[200050*5];int head[200000*5];int st,ed,cnt,maxcost;void add(int a,int b,int w,int c){ q[cnt].to = b; q[cnt].w = w; q[cnt].c = c; q[cnt].next = head[a]; head[a] = cnt++; q[cnt].to = a; q[cnt].w = 0; q[cnt].c = -c; q[cnt].next = head[b]; head[b] = cnt++;}struct no{ int a,b;}qq[200*4];int ha[40],dis[2010],flow;int f[2010],cur[2010];bool vis[2010];bool SPFA(){ memset(dis,inf,sizeof(dis)); memset(vis,false,sizeof(vis)); memset(cur,-1,sizeof(cur)); queue<int>Q; while(!Q.empty()) Q.pop(); Q.push(st); f[st]=inf; dis[st]=0; vis[st] = true; while(!Q.empty()){ int u = Q.front(); Q.pop(); vis[u] = false; for(int i = head[u];~i;i=q[i].next){ int v = q[i].to; if(dis[v] > dis[u] + q[i].c &&q[i].w > 0){ dis[v] = dis[u] + q[i].c; cur[v] = i; f[v] = min(f[u],q[i].w); if(!vis[v]){ vis[v] = true; Q.push(v); } } } } return dis[ed] != inf;}int so(){ int ant=0; for(int i = ed;i != st;i = q[cur[i]^1 ].to){ q[cur[i] ].w -= 1; q[cur[i]^1 ].w +=1; ant += q[cur[i] ].c; } return ant;}bool op(no x,no y){ if(x.a != y.a) return x.a<y.a; return x.b<y.b;}int main(){ int n,m,i,j,k,cla; while(~scanf("%d",&n)){ memset(ha,0,sizeof(ha)); maxcost=flow=cnt=0;st=0; int ans=0; memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); int s=0; for(i = 1;i <= n;++ i){ scanf("%d%d",&qq[i].a,&qq[i].b); s += qq[i].a*qq[i].b; } sort(qq+1,1+qq+n,op); for( i = 1; i <= n; ++ i){ add(st,i,1,0); } for(i = 1;i <= n;++i ){ for(j = 1;j < i;++ j){ if(qq[i].a >= qq[j].a && qq[i].b >= qq[j].b){ add(i,j+n,1,-(qq[j].a*qq[j].b)); } } } ed = 2 * n + 1; for(i = 1;i <= n;++ i){ add( i+n,ed,1,0 ); } int tmp=0; while(SPFA()){ tmp += so(); } printf("%d\n",s+tmp); } return 0;}
0 0
- 盒子嵌套问题 (二分图||费用流)
- 51 nod 1392 装盒子(费用流||二分图 骚)
- [网络流24题] 18 分配问题(二分图最佳匹配,最小费用最大流)
- hrbust 1492 盒子 (二分图匹配)
- zkw费用流模板(适用二分图)
- poj2195(二分图最大匹配,最小费用流)
- 二分图最大权匹配(费用流做法)
- 嵌套的盒子(居中)
- HDU1533/PKU2195 二分图匹配 费用流
- NOIP模拟 放盒子【费用流】
- 盒子嵌套
- 线性规划与网络流24题之分配问题 最大费用最大流、最小费用最大流、二分图的最佳匹配
- poj3685(嵌套二分)
- ural 1076 Trash 二分图最大权匹配(费用流实现)
- 求二分图最大权一个匹配(未必最大匹配),/费用流
- POJ-2195-Going Home(最小费用最大流/二分图)
- UVA 1349 Optimal Bus Route Design (最小费用流 -- 二分图最小权完美匹配)
- 9-13(周三训练赛-思路染色,费用流二分图Point)
- 持续集成篇_01_持续集成介绍及组成
- QT 处理中文乱码的问题
- C/C++ 服务端性能评测和检测优化工具
- 【数据结构与算法】十二 字符串搜索
- 编译全志A31出现的错误
- 盒子嵌套问题 (二分图||费用流)
- 用户协议
- 塔防游戏中iTweenPath路点插件的使用
- 二代旅游网站程序管理系统V1.0正式发布
- UESTC 1144 Big Brother
- reuseport+fastsocket
- [CODEVS1343][HNOI]蚱蜢(平衡树splay)
- mapreduce工作原理
- lintcode:Topological Sorting