POJ Ombrophobic Bovines 最大流建模
2017-08-24 10:17
399 查看
题目链接
http://poj.org/problem?id=2391题意
一个农场中有一些田地,每个田地有个躲雨的庇护所,但是庇护所的容量是有限的,给出一天田地之间的连接关系,以及田地上牛的数量,和庇护所的容量。假设走一单位距离花一单位时间,当下雨时,如何安排使得所有的牛都走到庇护所,并且花的时间最少,如果不满足输出-1.思路
和poj2112类似。不过这儿的图不是严格的“二分图”2112中奶牛在左机器在右,牛之间不会连边,机器之间也不会。只有左边和右边连边,这题如果二分一个距离假设为1,1->2 距离1 ,2->3 距离为1,都符合要求的距离,如果两条边都加入到图中,那么1->3 距离为2 的“边”也被加入了,突破了距离的限制。正确的建图方法是对一个点i拆点成i’,i”。并连接两条边(S,i’,C) , (i”,T,P) 。 C代表I点的牛的数量,P代表I点庇护所容量。如果原图中I到j有边,那么建边(i’,j”,INF)。输出-1的情况是,枚举到图中距离最远的两点依旧不能满足最大流等于所有牛的总数。#include<cstdio> #include<queue> #include<iostream> #include<vector> #include<map> #include<cstring> #include<string> #include<set> #include<stack> #include<algorithm> #define cle(a) memset(a,0,sizeof(a)) #define inf(a) memset(a,0x3f,sizeof(a)) #define ll long long #define Rep(i,a,n) for(int i=a;i<=n;i++) using namespace std; #define INF2 9223372036854775807ll const int INF = ( 2e9 ) + 2; const ll maxn = 410; const int maxm = 210; int n,m; ll maxx; int c[maxn],p[maxn]; ll mp[maxn][maxn]; struct edge { int from,to; ll c; edge(int getu,int getv,int getc) { from=getu; to=getv; c=getc; } }; struct Dinic { int s,t,n; ll d[maxn]; int cur[maxn]; vector<edge> e; vector<int> g[maxn]; void addedge(int u,int v,int c) { e.push_back(edge(u,v,c)); e.push_back(edge(v,u,0)); int m=e.size(); g[u].push_back(m-2); g[v].push_back(m-1); } void init() { e.clear(); for(int i=0; i<=maxn; i++) g[i].clear(); } bool bfs() { queue<int> q; q.push(s); memset(d,0,sizeof(d)); d[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=0; i<g[u].size(); i++) { int v=e[g[u][i]].to; int c=e[g[u][i]].c; if(!d[v]&&c) { d[v]=d[u]+1; q.push(v); } } } return d[t]; } int dfs(int u,int maxf,int t) { if(u==t)return maxf; int ret=0; for(int &i=cur[u]; i<g[u].size(); i++) { int c=e[g[u][i]].c; int v=e[g[u][i]].to; int f; if(d[u]+1==d[v]&&c) { f=dfs(v,min(maxf-ret,c),t); e[g[u][i]].c-=f; e[g[u][i]^1].c+=f; ret+=f; if(ret==maxf)return ret; } } return ret; } int maxflow(int s,int t) { this->s=s; this->t=t; int flow=0; while(bfs()) { memset(cur,0,sizeof(cur)); ll temp=dfs(s,INF,t); flow+=temp; } return flow; } } dinic; void Floyd(int n) { for(int k=1; k<=n; k++) { for(int i=1; i<=n; i++) { if(mp[i][k]==INF2)continue; for(int j=1; j<=n; j++) if(mp[k][j]!=INF2&&mp[i][j]>mp[i][k]+mp[k][j]) { mp[i][j]=mp[i][k]+mp[k][j]; if(maxx<mp[i][j])maxx=mp[i][j]; } } } } bool check(ll t,int tot) { for(int i=1; i<=n; i++) { dinic.addedge(0,i,c[i]); dinic.addedge(i+n,2*n+1,p[i]); dinic.addedge(i,i+n,INF); } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(mp[i][j]<=t) dinic.addedge(i,j+n,INF); int temp=dinic.maxflow(0,2*n+1); dinic.init(); return temp>=tot; } int main()// 拆点建立二分图,防止链连接突破最大距离限制源点到i' 边的容量为草场牛的数目,i''到汇点容量为庇护所容量 { // freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { ll tot=0; for(int i=1; i<=n; i++) scanf("%d%d",&c[i],&p[i]); for(int i=1; i<=n; i++) tot+=c[i]; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) mp[i][j]=INF2; for(int i=0; i<m; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); if(mp[u][v]>w)mp[u][v]=mp[v][u]=w; } maxx=0; Floyd(n); ll l=0,r=maxx+1; while(l<r) { ll mid=(l+r)>>1; if(check(mid,tot)) r=mid; else l=mid+1; } if(l>=maxx+1) printf("-1\n"); else printf("%lld\n",l); } }
相关文章推荐
- POJ 2391 Ombrophobic Bovines 最大流+二分
- Ombrophobic Bovines poj 2391 二分+拆点+最大流sap模板
- POJ 2391 Ombrophobic Bovines 不喜欢雨的奶牛 Floyd+二分枚举+最大流
- POJ 2391 Ombrophobic Bovines (最大流+二分答案)
- POJ-2391 Ombrophobic Bovines (二分答案+Floyd+拆点+最大流)
- poj 2391 Ombrophobic Bovines 二分+最大流
- POJ 2391 Ombrophobic Bovines 网络流 建模
- poj 2391 Ombrophobic Bovines 二分+拆点建图+最大流
- POJ 2391 Ombrophobic Bovines 拆点建图,二分答案,最大流
- [POJ 2391]Ombrophobic Bovines[最大流][二分答案]
- Ombrophobic Bovines POJ - 2391 Floyd+ 二分+最大流
- POJ-2391 Ombrophobic Bovines 二分+最大流+拆点
- POJ 2391 Ombrophobic Bovines (二分+最短路+最大流)
- POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)
- POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)
- POJ 2391 Ombrophobic Bovines 二分拆点最大流+floyd(高精度)
- POJ 2391 —— Ombrophobic Bovines 二分+Floyd+最大流
- POJ 2391 Ombrophobic Bovines 二分最大流+拆点
- POJ 2391.Ombrophobic Bovines (最大流)
- poj2391 Ombrophobic Bovines 拆点+二分法+最大流