poj 3498 (最大流,枚举汇点)
2013-08-14 09:17
351 查看
题意:有n块浮冰,每块上有一定数量的企鹅,每块浮冰可以承受企鹅跳一定的次数后消失,给出企鹅跳的最大距离,求所有企鹅能跳到哪块浮冰上见面。
建图:添加源点,汇点,源点与浮冰相连,容量为浮冰上企鹅的数量,浮冰之间可以相互连边,所以要拆点,拆完后点与拆点间连边,容量为浮冰能承受企鹅跳的次数,如果两块浮冰i,j间可以到达,加边i+n—>j,j+n—>i,容量无穷大。然后枚举所有浮冰与汇点相连求最大流。
建图:添加源点,汇点,源点与浮冰相连,容量为浮冰上企鹅的数量,浮冰之间可以相互连边,所以要拆点,拆完后点与拆点间连边,容量为浮冰能承受企鹅跳的次数,如果两块浮冰i,j间可以到达,加边i+n—>j,j+n—>i,容量无穷大。然后枚举所有浮冰与汇点相连求最大流。
#include<stdio.h> #include<string.h> const int N=210; const int inf=0x3fffffff; int dis ,gap ,head ,num,start,end,ans,n; struct edge { int st,ed,flow,next; }e[N*N]; struct node { double x,y; int cont,po; }P[210]; void addedge(int x,int y,int w) { e[num].st=x;e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++; e[num].st=y;e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++; } double Dis(int i,int j) { return (P[i].x-P[j].x)*(P[i].x-P[j].x)+(P[i].y-P[j].y)*(P[i].y-P[j].y); } int dfs(int u,int minflow) { if(u==end)return minflow; int i,v,f,flow=0,min_dis=ans-1; for(i=head[u];i!=-1;i=e[i].next) { if(e[i].flow>0) { v=e[i].ed; if(dis[v]+1==dis[u]) { f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow); e[i].flow-=f; e[i^1].flow+=f; flow+=f; if(flow==minflow)break; if(dis[start]>=ans)return flow; } min_dis=min_dis>dis[v]?dis[v]:min_dis; } } if(flow==0) { if(--gap[dis[u]]==0) dis[start]=ans; dis[u]=min_dis+1; gap[dis[u]]++; } return flow; } int isap() { int maxflow=0; memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); gap[0]=ans; while(dis[start]<ans) maxflow+=dfs(start,inf); return maxflow; } int main() { int i,j,sum,t,flag,k; double D; scanf("%d",&t); while(t--) { scanf("%d%lf",&n,&D); flag=0;sum=0; start=n+n;end=n+n+1;ans=end+1; for(i=0;i<n;i++) { scanf("%lf%lf%d%d",&P[i].x,&P[i].y,&P[i].cont,&P[i].po); sum+=P[i].cont; } for(k=0;k<n;k++) { memset(head,-1,sizeof(head));num=0; addedge(k,end,inf); for(i=0;i<n;i++) { addedge(i,i+n,P[i].po); addedge(start,i,P[i].cont); for(j=i+1;j<n;j++) { if(Dis(i,j)<=D*D) { addedge(i+n,j,inf); addedge(j+n,i,inf); } } } if(isap()==sum) { printf("%d ",k); flag++; } } if(flag==0)printf("-1\n"); else printf("\n"); } return 0; }
相关文章推荐
- poj 3498 (最大流,枚举汇点)
- POJ - 3498 March of the Penguins 最大流(拆点 + 枚举汇点)
- poj 3498(枚举汇点的最大流)
- POJ 3498 —— March of the Penguins (枚举+最大流)
- 51nod 1158 全是1的最大子矩阵 (暴力枚举)
- ACMjava求解最大连续和的三种方法 暴力枚举,S前缀,回溯法
- 经典题! 双指针枚举半平面,求最大最小值
- HDU 2236 矩阵不同行列寻找 最小最大数的差值 最小 二分匹配+二分枚举区间
- poj 3189 Steady Cow Assignment(最大流,枚举)
- POJ 3189 枚举+最大流判可行性
- nyoj 104 最大和(子矩阵最大和)(枚举)
- hdoj 5461 Largest Point 【枚举所有情况 找最大值】
- HDU 4309 Seikimatsu Occult Tonneru(最大流SAP+状态压缩枚举)
- hdu 3081 【二分匹配+并查集+删边||最大路+并查集+二分枚举】
- POJ 1459 Power Network【多源汇点最大流】
- HDU 1281 棋盘游戏 最大匹配+枚举
- 最大公约数(枚举和辗转相除法)
- nyoj 104 最大和(子矩阵最大和)(枚举)
- poj 3189(枚举加最大流)
- 最大乘积----简单枚举