POJ-2391 Ombrophobic Bovines 二分+最大流+拆点
2012-12-05 18:54
309 查看
题目链接:http://poj.org/problem?id=2391
这个题目很容易想到二分求解,我开始没有拆点,wa了很多次!后来发现,如果不拆点,二分枚举答案是没有意义的。因为在网络中,已建立的边可以相互联通,那么它们的距离相加可能会超过二分的限制,导致没有意义。那么我们可以把每个区域拆成两个点,一个在X集合,一个在Y集合,增加一个源点s和汇点t。从s向每个X集合得点建立边,容量为这个区域本原有的奶牛数,从每个Y集合的点建立边,容量为这个区域奶牛数的限制。然后,如果X集合点和Y集合点之间的最短距离小于二分限制的话那就建立边,容量为X集合点的原有的奶牛数。那么最大流就是可容纳的奶牛数量了。这个题目还有些细节问题值得注意,就是ans=-1的情况,还有就是long long的注意。开始这个我没注意好,贡献了很多次wa!
这个题目很容易想到二分求解,我开始没有拆点,wa了很多次!后来发现,如果不拆点,二分枚举答案是没有意义的。因为在网络中,已建立的边可以相互联通,那么它们的距离相加可能会超过二分的限制,导致没有意义。那么我们可以把每个区域拆成两个点,一个在X集合,一个在Y集合,增加一个源点s和汇点t。从s向每个X集合得点建立边,容量为这个区域本原有的奶牛数,从每个Y集合的点建立边,容量为这个区域奶牛数的限制。然后,如果X集合点和Y集合点之间的最短距离小于二分限制的话那就建立边,容量为X集合点的原有的奶牛数。那么最大流就是可容纳的奶牛数量了。这个题目还有些细节问题值得注意,就是ans=-1的情况,还有就是long long的注意。开始这个我没注意好,贡献了很多次wa!
//STATUS:G++_AC_188MS_1628KB #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<iostream> #include<string> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> using namespace std; #define LL __int64 #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int MAX=210,INF=0x3f3f3f3f; const LL LLNF=0x3f3f3f3f3f3f3f3fLL; struct Edge{ int u,v,cap; }e[MAX*MAX*2]; LL w[MAX][MAX],d[MAX*2]; int first[MAX*2],next[MAX*MAX*2],p[MAX*2]; int wt[MAX][MAX],cur[MAX*2],num[MAX*2],nod[MAX][2],inq[MAX]; int n,m,s,t,mt,tar,hav; LL maxlen,minlen; void adde(int a,int b,int val) { e[mt].u=a;e[mt].v=b; e[mt].cap=val; next[mt]=first[a];first[a]=mt++; e[mt].u=b;e[mt].v=a; e[mt].cap=0; next[mt]=first[b];first[b]=mt++; } void spfa(int s) { int i,x; queue<int> q; mem(inq,0); mem(d,0x3f); d[s]=0; q.push(s); while(!q.empty()){ x=q.front();q.pop(); inq[x]=0; for(i=1;i<=n;i++){ if(wt[x][i]!=INF && d[x]+wt[x][i]<d[i]){ d[i]=d[x]+wt[x][i]; if(!inq[i]){ inq[i]=1; q.push(i); } } } } } int augment() { int x=t,a=INF; while(x!=s){ a=Min(a,e[p[x]].cap); x=e[p[x]].u; } x=t; while(x!=s){ e[p[x]].cap-=a; e[p[x]^1].cap+=a; x=e[p[x]].u; } return a; } int isap() { int i,flow=0,x,ok; mem(d,0);mem(num,0); num[0]=t+1; for(i=0;i<=t;i++)cur[i]=first[i]; x=s; while(d[s]<=t){ if(x==t){ flow+=augment(); x=s; } ok=0; for(i=cur[x];i!=-1;i=next[i]){ if(e[i].cap && d[x]==d[e[i].v]+1){ ok=1; p[e[i].v]=i; cur[x]=i; x=e[i].v; break; } } if(!ok){ int m=t; for(i=first[x];i!=-1;i=next[i]) if(e[i].cap && d[e[i].v]<m)m=d[e[i].v]; if(--num[d[x]]==0)break; num[d[x]=m+1]++; cur[x]=first[x]; if(x!=s)x=e[p[x]].u; } } return flow; } LL binary() { int i,j; LL low=minlen-1,high=maxlen+1,mid; while(low<high){ mid=(low+high)>>1; mt=0; mem(first,-1); for(i=1;i<=n;i++){ if(nod[i][0]){ adde(s,i,nod[i][0]); for(j=1;j<=n;j++) if(w[i][j]<=mid) adde(i,n+j,nod[i][0]); } adde(n+i,t,nod[i][1]); } int tt=isap(); if(tt<tar)low=mid+1; else high=mid; } return low==maxlen+1?-1:low; } int main() { // freopen("in.txt","r",stdin); int i,j,a,b,val; LL ans; while(~scanf("%d%d",&n,&m)) { tar=hav=0; s=0;t=2*n+1; maxlen=-LLNF,minlen=LLNF; mem(w,0x3f); mem(wt,0x3f); for(i=1;i<=n;i++){ scanf("%d%d",&nod[i][0],&nod[i][1]); tar+=nod[i][0];hav+=nod[i][1]; } if(tar<=hav){ for(i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&val); if(val<wt[a][b])wt[a][b]=wt[b][a]=val; } for(i=1;i<=n;i++){ spfa(i); for(j=1;j<=n;j++){ w[j][i]=d[j]; if(d[j]<minlen && i!=j)minlen=d[j]; if(d[j]>maxlen && d[j]!=LLNF)maxlen=d[j]; } } ans=binary(); } else { ans=-1; while(m--)scanf("%d%d%d",&a,&a,&a); } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- POJ 2391 Ombrophobic Bovines 最大流+二分
- POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)
- POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)
- Ombrophobic Bovines POJ - 2391 Floyd+ 二分+最大流
- poj 2391 Ombrophobic Bovines 二分+最大流
- POJ 2391 Ombrophobic Bovines 拆点建图,二分答案,最大流
- POJ 2391 Ombrophobic Bovines (二分+最短路+最大流)
- POJ 2391 Ombrophobic Bovines 二分最大流+拆点
- Ombrophobic Bovines poj 2391 二分+拆点+最大流sap模板
- POJ 2391 —— Ombrophobic Bovines 二分+Floyd+最大流
- [POJ 2391]Ombrophobic Bovines[最大流][二分答案]
- POJ 2391 Ombrophobic Bovines (最大流+二分答案)
- POJ-2391 Ombrophobic Bovines (二分答案+Floyd+拆点+最大流)
- POJ 2391 Ombrophobic Bovines 不喜欢雨的奶牛 Floyd+二分枚举+最大流
- poj 2391 Ombrophobic Bovines 二分+拆点建图+最大流
- POJ 2391 Ombrophobic Bovines 二分拆点最大流+floyd(高精度)
- POJ 2391.Ombrophobic Bovines (最大流)
- 【POJ 2391 】Ombr 4000 ophobic Bovines 【floyd +二分+最大流】
- poj 2391 Ombrophobic Bovines 【floyd + 二分 + 拆点网络流】
- Ombrophobic Bovines (poj 2391 网络流+二分+Floyd)