Assignment 8: Network Flow Problems
来源:互联网 发布:云计算是什么工作 编辑:程序博客网 时间:2024/05/21 19:49
1273 Drainage Ditches (1)
1274 The Perfect Stall (1)
2112 Optimal Milking (4)
3041 Asteroids (5)
3308 Paratroopers (6)
2195 Going Home (6)
2516 Minimum Cost (7)
2455 Secret Milking Machine (7)
2226 Muddy Fields (7)
3281 Dining (7)
2391 Ombrophobic Bovines (8, challenge problem)
3498 March of the Penguins (8, challenge problem)
poj2195
最小费用二分图匹配的三种方式
#include <cmath>#include <vector>#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;typedef vector<int> VI;typedef vector<VI> VVI;typedef long long L;typedef vector<L> VL;typedef vector<VL> VVL;typedef pair<int, int> PII;typedef vector<PII> VPII;typedef vector<double> VD;typedef vector<VD> VVD;const L INF = 0x3f3f3f3f;struct MinCostMaxFlow {int N;VVL cap, flow, cost;VI found;VL dist, pi, width;VPII dad;MinCostMaxFlow(int N) :N(N), cap(N, VL(N)), flow(N, VL(N)), cost(N, VL(N)),found(N), dist(N), pi(N), width(N), dad(N) {}void AddEdge(int from, int to, L cap, L cost) {this->cap[from][to] = cap;this->cost[from][to] = cost;}void Relax(int s, int k, L cap, L cost, int dir) {L val = dist[s] + pi[s] - pi[k] + cost;if (cap && val < dist[k]) {dist[k] = val;dad[k] = make_pair(s, dir);width[k] = min(cap, width[s]);}}L Dijkstra(int s, int t) {fill(found.begin(), found.end(), false);fill(dist.begin(), dist.end(), INF);fill(width.begin(), width.end(), 0);dist[s] = 0;width[s] = INF;while (s != -1) {int best = -1;found[s] = true;for (int k = 0; k < N; k++) {if (found[k]) continue;Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);Relax(s, k, flow[k][s], -cost[k][s], -1);if (best == -1 || dist[k] < dist[best]) best = k;}s = best;}for (int k = 0; k < N; k++)pi[k] = min(pi[k] + dist[k], INF);return width[t];}pair<L, L> GetMaxFlow(int s, int t) {L totflow = 0, totcost = 0;while (L amt = Dijkstra(s, t)) {totflow += amt;for (int x = t; x != s; x = dad[x].first) {if (dad[x].second == 1) {flow[dad[x].first][x] += amt;totcost += amt * cost[dad[x].first][x];} else {flow[x][dad[x].first] -= amt;totcost -= amt * cost[x][dad[x].first];}}}return make_pair(totflow, totcost);}};int ht,mt;char mat[110][110];typedef pair<int,int> pii;pii house[110],man[110];int dis(int i,int j){ return abs(house[i].first-man[j].first)+abs(house[i].second-man[j].second);}void gao_mcmf(){ MinCostMaxFlow my(ht+ht+2); for(int i=0;i<ht;++i){ my.AddEdge(0,i+1,1,0); my.AddEdge(i+ht+1,ht+ht+1,1,0); for(int j=0;j<ht;++j){ my.AddEdge(i+1,ht+j+1,1,dis(i,j)); } } printf("%lld\n",my.GetMaxFlow(0,ht+ht+1).second);}//////////////////////////////////////////////////////////////////////////////double MinCostMatching(const VVD &cost, VI &Lmate, VI &Rmate) { int n = int(cost.size()); // construct dual feasible solution VD u(n); VD v(n); for (int i = 0; i < n; i++) { u[i] = cost[i][0]; for (int j = 1; j < n; j++) u[i] = min(u[i], cost[i][j]); } for (int j = 0; j < n; j++) { v[j] = cost[0][j] - u[0]; for (int i = 1; i < n; i++) v[j] = min(v[j], cost[i][j] - u[i]); } // construct primal solution satisfying complementary slackness Lmate = VI(n, -1); Rmate = VI(n, -1); int mated = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (Rmate[j] != -1) continue; if (fabs(cost[i][j] - u[i] - v[j]) < 1e-10) {Lmate[i] = j;Rmate[j] = i;mated++;break; } } } VD dist(n); VI dad(n); VI seen(n); // repeat until primal solution is feasible while (mated < n) { // find an unmatched left node int s = 0; while (Lmate[s] != -1) s++; // initialize Dijkstra fill(dad.begin(), dad.end(), -1); fill(seen.begin(), seen.end(), 0); for (int k = 0; k < n; k++) dist[k] = cost[s][k] - u[s] - v[k]; int j = 0; while (true) { // find closest j = -1; for (int k = 0; k < n; k++) {if (seen[k]) continue;if (j == -1 || dist[k] < dist[j]) j = k; } seen[j] = 1; // termination condition if (Rmate[j] == -1) break; // relax neighbors const int i = Rmate[j]; for (int k = 0; k < n; k++) {if (seen[k]) continue;const double new_dist = dist[j] + cost[i][k] - u[i] - v[k];if (dist[k] > new_dist) { dist[k] = new_dist; dad[k] = j;} } } // update dual variables for (int k = 0; k < n; k++) { if (k == j || !seen[k]) continue; const int i = Rmate[k]; v[k] += dist[k] - dist[j]; u[i] -= dist[k] - dist[j]; } u[s] += dist[j]; // augment along path while (dad[j] >= 0) { const int d = dad[j]; Rmate[j] = Rmate[d]; Lmate[Rmate[j]] = j; j = d; } Rmate[j] = s; Lmate[s] = j; mated++; } double value = 0; for (int i = 0; i < n; i++) value += cost[i][Lmate[i]]; return value;}VI Lmate,Rmate;void gao_mcmatch(){ VD temp(ht,0); VVD cost(ht,temp); for(int i=0;i<ht;++i){ for(int j=0;j<ht;++j){ cost[i][j]=dis(i,j); } } printf("%.0f\n",MinCostMatching(cost,Lmate,Rmate));}////////////////////////////////////////////////////////////////////////////////#define maxn 210struct NODE{ NODE(){} NODE(int uu,int vv,int cc,int ww,int pp):u(uu),v(vv),c(cc),w(ww),p(pp){} int u,v,c,w,p;};vector<NODE> adj[maxn],nu;vector<NODE>::iterator pre[maxn];queue<int> q;int cnt[maxn];int d[maxn];bool vis[maxn];void add(int u,int v,int c,int w){ adj[u].push_back(NODE(u,v,c,w,adj[v].size())); adj[v].push_back(NODE(v,u,0,-w,adj[u].size()-1));}int n;int spfa(){ while(!q.empty()) q.pop(); fill(d,d+n+2,INF); memset(cnt,0,sizeof(cnt)); memset(vis,0,sizeof(vis)); d[0]=0; cnt[0]=1; vis[0]=1; pre[0]=nu.begin(); q.push(0); int u,v,c; vector<NODE>::iterator it; while(!q.empty()){ u=q.front(); q.pop(); vis[u]=0; for(it=adj[u].begin();it!=adj[u].end();++it){ v=it->v; if(it->c && d[v]>d[u]+it->w){ d[v]=d[u]+it->w; pre[v]=it; if(!vis[v]){ if(++cnt[v]>n+1) return 0; vis[v]=1; q.push(v); } } } } if(d[n+1]==INF) return 0; return 1;}int mfmc(){ int ans=0,m; vector<NODE>::iterator it; while(spfa()){ m=INF; for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){ m=min(m,it->c); } for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){ it->c-=m; adj[it->v][it->p].c+=m; } ans+=m*d[n+1]; } return ans;}void gao_mfmc(){ int i,j; n=ht+ht; for(i=0;i<=n+1;++i) adj[i].clear(); for(int i=0;i<ht;++i){ add(0,i+1,1,0); add(i+ht+1,n+1,1,0); for(int j=0;j<ht;++j){ add(i+1,ht+j+1,1,dis(i,j)); } } printf("%d\n",mfmc());}///////////////////////////////////////////////////////////////////////////int main(){ int m,n,i,j; while(scanf("%d%d",&m,&n)!=EOF && m){ ht=mt=0; for(i=0;i<m;++i){ scanf("%s",mat[i]); for(j=0;j<n;++j){ if(mat[i][j]=='H') { house[ht].first=i,house[ht].second=j; ++ht; }else if(mat[i][j]=='m'){ man[mt].first=i,man[mt].second=j; ++mt; } } } // gao_mcmf(); // gao_mcmatch(); gao_mfmc(); } return 0;}
poj2516
最大流最小费模板
#include <cmath>#include <vector>#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define INF 0x3f3f3f3f#define maxn 110int cost[55][55][55];int buy[55][55],sell[55][55],bt[55],st[55];struct NODE{ NODE(){} NODE(int uu,int vv,int cc,int ww,int pp):u(uu),v(vv),c(cc),w(ww),p(pp){} int u,v,c,w,p;};vector<NODE> adj[maxn],nu;vector<NODE>::iterator pre[maxn];queue<int> q;int cnt[maxn];int d[maxn];bool vis[maxn];void add(int u,int v,int c,int w){ adj[u].push_back(NODE(u,v,c,w,adj[v].size())); adj[v].push_back(NODE(v,u,0,-w,adj[u].size()-1));}int n,B,S,K;int spfa(){ while(!q.empty()) q.pop(); fill(d,d+n+2,INF); memset(cnt,0,sizeof(cnt)); memset(vis,0,sizeof(vis)); d[0]=0; cnt[0]=1; vis[0]=1; pre[0]=nu.begin(); q.push(0); int u,v,c; vector<NODE>::iterator it; while(!q.empty()){ u=q.front(); q.pop(); vis[u]=0; for(it=adj[u].begin();it!=adj[u].end();++it){ v=it->v; if(it->c && d[v]>d[u]+it->w){ d[v]=d[u]+it->w; pre[v]=it; if(!vis[v]){ if(++cnt[v]>n+1) return 0; vis[v]=1; q.push(v); } } } } if(d[n+1]==INF) return 0; return 1;}int mfmc(){ int ans=0,m; vector<NODE>::iterator it; while(spfa()){ m=INF; for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){ m=min(m,it->c); } for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){ it->c-=m; adj[it->v][it->p].c+=m; } ans+=m*d[n+1]; } return ans;}int gao_mfmc(int k){ int i,j; for(i=0;i<=n+1;++i) adj[i].clear(); for(i=0;i<S;++i){ add(0,i+1,sell[k][i],0); } for(i=0;i<B;++i){ add(i+S+1,n+1,buy[k][i],0); } for(i=0;i<B;++i){ for(j=0;j<S;++j){ add(j+1,i+S+1,INF,cost[k][i][j]); } } return mfmc();}int main(){ int i,j,k; while(scanf("%d%d%d",&B,&S,&K)!=EOF && B){ n=B+S; memset(bt,0,sizeof(bt)); memset(st,0,sizeof(st)); for(i=0;i<B;++i){ for(j=0;j<K;++j){ scanf("%d",&buy[j][i]); bt[j]+=buy[j][i]; } } for(i=0;i<S;++i){ for(j=0;j<K;++j){ scanf("%d",&sell[j][i]); st[j]+=sell[j][i]; } } for(k=0;k<K;++k){ for(i=0;i<B;++i){ for(j=0;j<S;++j){ scanf("%d",&cost[k][i][j]); } } } int ok=1; for(i=0;i<K;++i){ if(bt[i]>st[i]){ ok=0; break; } } if(!ok){ printf("-1\n"); continue; } int ans=0; for(i=0;i<K;++i){ ans+=gao_mfmc(i); } printf("%d\n",ans); } return 0;}
poj2226以连续线段为结点,最大二分匹配(匈牙利算法)
#include<cstdio>#include<cstring>#define maxn 1300int mat[maxn][maxn],match[maxn];bool vis[maxn];char map[55][55];int r[55][55],c[55][55];int cntr,cntc;int m,n;bool dfs(int i){ int j; for(j=0;j<cntc;++j){ if(!mat[i][j] || vis[j]) continue; vis[j]=1; if(match[j]==-1 || dfs(match[j])){ match[j]=i; return 1; } } return 0;}int main(){ // freopen("d.in","r",stdin); int i,j,ans=0; memset(match,-1,sizeof(match)); scanf("%d%d",&m,&n); for(i=0;i<m;++i){ scanf("%s",map[i]); map[i][n]='.'; } for(i=0;i<n;++i) map[m][i]='.'; for(i=0;i<m;++i){ for(j=0;j<=n;++j){ if(map[i][j]=='*') r[i][j]=cntr; else if(j>0 && map[i][j-1]=='*') ++cntr; } } for(j=0;j<n;++j){ for(i=0;i<=m;++i){ if(map[i][j]=='*') c[i][j]=cntc; else if(i>0 && map[i-1][j]=='*') ++cntc; } } for(i=0;i<m;++i){ for(j=0;j<n;++j){ if(map[i][j]=='*'){ mat[r[i][j]][c[i][j]]=1; } } } for(i=0;i<cntr;++i){ memset(vis,0,sizeof(vis)); if(dfs(i)) ++ans; } printf("%d\n",ans); return 0;}
poj2391floyd+离散化+二分+dinic
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;typedef long long u64;typedef int type;#define maxn 205#define maxm 81205#define INF 0x3ffffffffffffLL#define inf 0x3f3f3f3fstruct EDGE{ int v,next; type c;}edge[maxm];u64 mat[maxn][maxn];int n,N,M;int have[maxn],hold[maxn];int d[maxn<<1],head[maxn<<1];int src,des,tot,all;void init(){ memset(head,-1,sizeof(head)); tot=0;}void add(int u,int v,type c){ edge[tot].v=v,edge[tot].c=c,edge[tot].next=head[u];head[u]=tot++; edge[tot].v=u,edge[tot].c=0,edge[tot].next=head[v];head[v]=tot++;}queue<int> q;bool bfs(){ while(!q.empty()) q.pop(); int u,v,i; type c; memset(d,-1,sizeof(d)); d[src]=0; q.push(src); while(!q.empty()){ u=q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; c=edge[i].c; if(c>0 && d[v]==-1){ d[v]=d[u]+1; q.push(v); } } } return (d[des]!=-1);}type dfs(int u,type mm){ if(u==des) return mm; int i,v; type c,temp; for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; c=edge[i].c; if(c>0 && d[v]==d[u]+1 && (temp=dfs(v,min(mm,c)))){ edge[i].c-=temp; edge[i^1].c+=temp; return temp; } } d[u]=-1; return 0;}type dinic(){ type ans=0,temp; while(bfs()){ while(1){ temp=dfs(src,inf); if(!temp) break; ans+=temp; } } return ans;}bool check(u64 k){ int i,j; init(); for(i=1;i<=N;++i){ for(j=1;j<=N;++j){ if(mat[i][j]<=k && i!=j && have[i]){ add(i,j+N,have[i]); } } if(have[i]){ add(i,N+i,have[i]); add(src,i,have[i]); } if(hold[i]){ add(i+N,des,hold[i]); } } if(dinic()==all) return 1; return 0;}u64 h[maxn*maxn];int cnt;int main(){ //freopen("data.in","r",stdin);//freopen("data.out","w",stdout); int i,j,u,v,k,l,r,m; u64 c; scanf("%d%d",&N,&M); for(i=1;i<=N;++i){ scanf("%d%d",&have[i],&hold[i]); all+=have[i]; for(j=1;j<=N;++j) mat[i][j]=INF; } while(M--){ scanf("%d%d%lld",&u,&v,&c); mat[u][v]=min(mat[u][v],c); mat[v][u]=min(mat[v][u],c); } for(k=1;k<=N;++k){ for(i=1;i<=N;++i){ for(j=1;j<=N;++j){ mat[i][j]=min(mat[i][j],mat[i][k]+mat[k][j]); } } } cnt=1; for(i=1;i<=N;++i){ for(j=i+1;j<=N;++j){ if(mat[i][j]!=INF){ h[cnt++]=mat[i][j]; } } } n=N+N+2; src=0,des=n-1; sort(h,h+cnt); cnt=unique(h,h+cnt)-h; l=0,r=cnt-1; if(!check(h[r])){ printf("-1\n"); return 0; } while(l+1<r){ m=(l+r)>>1; // printf("l=%d r=%d h[m]=%lld\n",l,r,h[m]); if(check(h[m])) r=m; else l=m; } printf("%lld\n",h[r]); return 0;}
- Assignment 8: Network Flow Problems
- Network problems last Friday
- [4_4_milk6] Network flow
- 网络流(Network Flow)
- HDOJ 3549 Flow Problem(network flow)
- Possible Firewall-Induced Network Problems
- 网络流(Network Flow)
- network flow based on BFS
- Assignment 8
- zigbee中网络地址分配(Network address assignment)
- m2eclipse:Network connection problems encountered during search
- Network Data Flow through the Linux Kernel
- 在图论中,网络流(Network Flow)
- hdu 1532 Network Flow Drainage Ditches
- Deep Network Flow for Multi-Object Tracking
- 网络流算法(Network Flow)
- Assignment
- Problems with opening CHM Help files from Network or Internet
- maven项目从myeclipse转到eclipse的艰辛历程
- hdu 4630 no pain no game 树状数组+离线查询
- Java多线程
- 数字组合
- 联想s310/s410/s415/s400由uefi boot转legacy boot
- Assignment 8: Network Flow Problems
- OBTAINING SPRING 3 ARTIFACTS WITH MAVEN
- Ubuntu 没有mkinitrd 解决方法
- delphi2010的编码问题
- UML类图几种关系的总结
- 进程间相互传送数据(delphi2010)
- Delphi里面hwnd跟Thandle有什么区别?
- 【Java】鼠标监听器MouseListener和MouseMotionListener的使用
- 集合框架(1)