太空飞行计划问题(网络流24题,七)
来源:互联网 发布:微软办公软件国际认证 编辑:程序博客网 时间:2024/05/16 14:05
太空飞行计划问题
题目分析:
是一道中问题,就不深入的分析了。就是叫你求给你M个实验,N个仪器。每个实验要用到N个仪器中的一些,而每个仪使用每个仪器都要花费一些钱。而完成每个实验会有一定的报酬,现在叫你求出最大的利润。
利润 = 总收益 - 总花费
算法分析:
最大权闭合子图。
建模分析:
我们可以根据最大闭合子图的算法思想,建立一个图。
1、我们建立两个超级点S,T。
2、对每个实验跟S链接一条容量为收入的边。
3、对每个一起跟T链接一条容量为花费的边。
4、对每个实验要用到的一起链接一条容量为无穷大的边。
C语言链表实现:
#include <iostream>#include <queue>#include <vector>#include <cstdio>#include <cstring>using namespace std; const int MAXN = 101,MAXM = MAXN*MAXN*2,INF = ~0U >> 1;struct Edge{ Edge *next,*op; int t,c;}*V[MAXN],*P[MAXN],ES[MAXM],*Stae[MAXN];int N,M,S,T,EC,Ans,Maxflow;int Lv[MAXN],Stap[MAXN];void Clear(){ for(int i = 0;i < MAXN;++i) V[i] = NULL,ES[i].next = NULL,ES[i].op = NULL; EC = 0; Ans = 0; Maxflow = 0;}inline void addedge(int a,int b,int c){ ES[++EC].next = V[a];V[a] = ES+EC;V[a]->t = b;V[a]->c = c; ES[++EC].next = V[b];V[b] = ES+EC;V[b]->t = a;V[b]->c = 0; V[a]->op = V[b]; V[b]->op = V[a];}bool Dinic_Lable() //构造层次图{ int head,tail,i,j; Stap[head=tail=0] = S; memset(Lv,-1,sizeof(Lv)); Lv[S] = 0; while(head<=tail){ i = Stap[head++]; for(Edge *e = V[i];e;e = e->next){ j = e->t; if(e->c&&Lv[j]==-1){ Lv[j] = Lv[i] + 1; if(j==T) return true; Stap[++tail] = j; } } } return false;}void Dinic_Augment() //增广{ int i,j,delta,Stop; for(i = S;i <= T;++i) P[i] = V[i]; Stap[Stop=1] = S; while(Stop){ i = Stap[Stop]; if(i != T){ for(;P[i];P[i] = P[i]->next) if(P[i]->c&&Lv[i]+1==Lv[j=P[i]->t]) break; if(P[i]){ Stap[++Stop] = j; Stae[Stop] = P[i]; } else Stop--,Lv[i] = -1; } else { delta = INF; for(i = Stop;i >= 2;--i) if(Stae[i]->c < delta) delta = Stae[i]->c; Maxflow += delta; for(i = Stop;i >= 2;--i){ Stae[i]->c -= delta; Stae[i]->op->c += delta; if(Stae[i]->c == 0) Stop = i-1; } } }}void Dinic(){ while(Dinic_Lable()) Dinic_Augment();}void init(){ int i,a,c; S = 0; T = M+N+1; for(i = 1;i <= M;++i){ scanf("%d",&c); addedge(S,i,c); Ans += c;// for(;;){// int sum = 0;// c = getchar();// while(c == ' ')c = getchar();// if(c=='\n') break;// while(c!=' '&&c!='\n'){// sum *= 10;// sum += c - '0';// c = getchar();// } printf("sum == %d\n",sum);// addedge(i,sum+M,INF);// if(c=='\n') break;// } for (;;){ while((c=getchar())==' '); ungetc(c,stdin); if (c==10 || c==13) break; scanf("%d",&a); addedge(i,a+M,INF); } } for(i = 1;i <= N;++i){ scanf("%d",&c); addedge(i+M,T,c); }}void print(){ for(int i = 1;i <= M;++i) if(Lv[i]!=-1) printf("%d ",i); putchar('\n'); for(int i = M+1;i <= M+N;++i) if(Lv[i]!=-1) printf("%d ",i-M); Ans -= Maxflow; printf("\n%d\n",Ans);}int main(){// freopen("Input.txt","r",stdin); while(~scanf("%d%d",&M,&N)){ Clear(); init(); Dinic(); print(); } return 0;}
C++容器实现:
#include <iostream>#include <algorithm>#include <sstream>#include <vector>#include <queue>#include <cstdio>#include <cstring>using namespace std; const int MAXN = 1e3 + 5,INF = ~0U >> 2;struct Edge{ int from,to,cap,flow; Edge(int f,int t,int c,int _f) :from(f),to(t),cap(c),flow(_f){};};vector<Edge> edges;vector<int> G[MAXN];int N,M,S,T;int d[MAXN],cur[MAXN];bool vst[MAXN];void Init(){ for(int i = 0;i < MAXN;++i) G[i].clear(); edges.clear();}inline void AddEdge(int from,int to,int cap){ edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); int sz = edges.size(); G[from].push_back(sz-2); G[to].push_back(sz-1);}bool BFS(){ memset(vst,false,sizeof(vst)); queue<int> Q; Q.push(S); d[S] = 0; vst[S] = true; while(!Q.empty()){ int x = Q.front(); Q.pop(); for(int i = 0;i < (int)G[x].size();++i){ Edge& e = edges[G[x][i]]; if(!vst[e.to]&&e.cap>e.flow){ vst[e.to] = true; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vst[T];}int DFS(int u,int a){ if(u==T||a==0) return a; int f,flow = 0; for(int& i = cur[u];i < (int)G[u].size();++i){ Edge& e = edges[G[u][i]]; if(d[u]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow += f; edges[G[u][i]^1].flow -= f; flow += f; a -= f; if(a==0)break; } } return flow;}int Maxflow(){ int flow = 0; while(BFS()){ memset(cur,0,sizeof(cur)); flow += DFS(S,INF); } return flow;}void Solve(){ int i,c,ans = 0; S = 0; T = M+N+1; for(i = 1;i <= M;++i){ scanf("%d",&c); AddEdge(S,i,c); ans += c; string str; getline(cin,str); istringstream ssin(str); while(ssin>>c) AddEdge(i,c+M,INF); } for(i = 1;i <= N;++i){ scanf("%d",&c); AddEdge(i+M,T,c); } int maxflow = Maxflow(); for(i = 1;i <= M;++i) if(vst[i]) printf("%d ",i); putchar('\n'); for(i = M+1;i <= M+N;++i) if(vst[i]) printf("%d ",i-M); printf("\n%d\n",ans-maxflow);}int main(){// freopen("Input.txt","r",stdin); while(~scanf("%d%d",&M,&N)){ Init(); Solve(); } return 0;}
4 0
- 太空飞行计划问题(网络流24题,七)
- 【网络流24题】太空飞行计划问题
- 【网络流24题】太空飞行计划问题
- 网络流24题:太空飞行计划问题
- 线性规划与网络流24题 02太空飞行计划问题
- 网络流与线性规划24题02太空飞行计划问题
- [网络流24题 #2]太空飞行计划问题
- 【网络流24题】太空飞行计划问题 …
- kyeremal-网络流24题T2-太空飞行计划问题
- 太空飞行计划问题[网络流24题之2]
- 网络流24题——太空飞行计划问题
- 网络流24题之太空飞行计划问题(nefu476)
- 网络流24题2 太空飞行计划问题 洛谷 2762
- 网络流24题2 太空飞行计划问题
- [网络流24题][洛谷P2762]太空飞行计划问题
- 网络流24题2. 太空飞行计划问题
- 【网络流】太空飞行计划问题
- [网络流24题] 太空飞行计划
- [LeetCode 14] Longest Common Prefix Solutions
- SimHash-大数据文本去重的方法之一
- linux内存碎片管理
- NSDate管理日期和时间
- myeclipse的启动项优化操作
- 太空飞行计划问题(网络流24题,七)
- Linux终端显示混乱
- 《高质量程序设计指南:C++/C语言》 林锐
- Java架构介绍(二)
- 不同数据库中的分页查询方法
- 红尘有梦,转身便是风景
- js--easyUI datetimebox 自定义显示格式 .
- Microformat
- 《嵌入式Linux开发实用教程》