LA2957 网络流 蓝书例题
来源:互联网 发布:手机dns优选软件 编辑:程序博客网 时间:2024/05/12 19:34
分析:
首先假设答案为T。构图如下:
把原图的每个点u拆成T+1个,分别为u0,u1,......, 其中u0是初始状态的结点u,ui表示经过i天之后的结点u。对于原图中的相邻结点a和b,在新图中添加一条从ai到bi+1的边,容量为1,再添加一条bi到ai+1的边,容量也为1。对于原图中的每个结点u,添加
ui->ui+1,容量为无穷大,表示飞船可以原地不动。在此图中求最大流,判断流量是否至少为k即可。
逐步增大天数T,每次不要重新求最大流,直接加上一层结点,在上次求出的最大流基础上继续增广,直到流量达到k。
注意,同一时刻ai->bi+1和bi->ai+1不能同时有流量。
代码如下:
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;const int INF = 1e9;const int maxn = 5000+10;const int maxm = 200+10;struct Edge{ int from,to,cap,flow;};bool operator < (const Edge &a,const Edge &b){ return a.from<b.from || (a.from == b.from && a.to<b.to);}vector<Edge>edges;vector<int>G[maxn];bool vis[maxn]; //BFS使用int d[maxn]; //起点到i的距离int cur[maxn]; //当前弧指针int n,m,s,t,k;int u[maxm],v[maxm];queue<int>que;void clearNodes(int a, int b){ for (int i=a; i<=b; i++) G[i].clear();}void init(){ edges.clear(); clearNodes(0,n-1); for (int i=0; i<m; i++) scanf("%d %d",&u[i],&v[i]);}int sz;void AddEdge(int from, int to, int cap){ edges.push_back((Edge){from,to,cap,0}); edges.push_back((Edge){to,from,0,0}); sz = edges.size(); G[from].push_back(sz-2); G[to].push_back(sz-1);}bool BFS(int s, int t){ memset(vis,0,sizeof(vis)); while (!que.empty()) que.pop(); que.push(s); vis[s] = 1; d[s] = 0; int x; while (!que.empty()){ x = que.front(); que.pop(); for (int i=0; i<G[x].size(); i++) { Edge &e = edges[G[x][i]]; if (!vis[e.to] && e.cap>e.flow) { vis[e.to] = 1; d[e.to] = d[x] + 1; que.push(e.to); } } } return vis[t];}inline int MIN(int x, int y){return x<y?x:y;}int DFS(int x,int t, int a){ if (x==t || a==0) return a; int flow = 0, f; for (int &i=cur[x]; i<G[x].size(); i++){ Edge &e = edges[G[x][i]]; if (d[x]+1==d[e.to] && (f=DFS(e.to,t,MIN(a,e.cap-e.flow)))>0){ flow += f; a -= f; e.flow += f; edges[G[x][i]^1].flow -= f; if (a==0) break; } } return flow;}int MAXflow(int s, int t, int limit){ int flow = 0; while (BFS(s,t)){ memset(cur,0,sizeof(cur)); flow += DFS(s,t,limit-flow); if (flow==limit) break; } return flow;}int day,flow;void Print(){ printf("%d\n",day); int idx = 0; vector<int> location(k,s); for (int d=1; d<=day; d++){ idx += n*2; vector<int>moved(k,0); vector<int>a,b; for (int i=0; i<m; i++) { int f1 = edges[idx].flow; idx+=2; int f2 = edges[idx].flow; idx+=2; if (f1==1 && f2==0) {a.push_back(u[i]); b.push_back(v[i]);} if (f1==0 && f2==1) {a.push_back(v[i]); b.push_back(u[i]);} } printf("%d",a.size()); for (int i=0; i<a.size(); i++) { //查找哪架飞船从a[i]移动到b[i] for (int j=0; j<k; j++) if (!moved[j] && location[j]==a[i]){ printf(" %d %d",j+1,b[i]); moved[j] = 1; location[j] = b[i]; break; } } printf("\n"); }}int main(){ while (scanf("%d %d %d %d %d",&n,&m,&k,&s,&t)==5){ init(); day = 1, flow = 0; for (;;){ clearNodes(day*n,day*n+n-1); for (int i=0; i<n; i++) AddEdge((day-1)*n+i,day*n+i,INF); for (int i=0; i<m; i++) { AddEdge((day-1)*n + u[i]-1, day*n+v[i]-1,1); AddEdge((day-1)*n + v[i]-1, day*n+u[i]-1,1); } flow += MAXflow(s-1, day*n + t-1, k-flow); if (k==flow) break; day++; } Print(); } return 0;}
阅读全文
0 0
- LA2957 网络流 蓝书例题
- 运送超级计算机 分裂点 网络流 LA2957/UVa1324 Bring Them There
- 网络流例题总结
- 网络流例题
- RMQ ST算法 uva11235(蓝书例题)
- 网络流(模版+例题)
- 网络流例题及构图选讲
- 例题15 网络
- 【例题】【网络流(费用流)】NKOJ 3738 学号
- 网络流 - Edmond-Karp 小讲 【 理解 + 例题 】 更新 ing...
- 蓝队网络工作日志
- 例题1.15 网络 UVALive 3902
- 例题3.6 合作网络 UVa1329
- 例题5.22 比赛网络 UVa11865
- 蓝桥 历届试题 网络寻路
- 蓝
- java例题学习:字符流例题
- 【例题】【费用流(影响未来问题 )】NKOJ1945 【线性规划与网络流24题 10】餐巾计划
- 层次路由
- 今天申请了C博客,心情十分激动!
- 计算机体系结构--进制及运算
- docker 学习笔记入门(安装docker-io)
- 用python实现Pat1015德才论
- LA2957 网络流 蓝书例题
- Java面向对象的本质
- tensorflow显存、载入模型、优化器(个人笔记)
- 你会安装软件吗?
- perception感知机
- 洛谷1462 通往奥格瑞玛的道路
- 【JZOJ 5435】【NOIP2017提高A组集训10.30】Graph
- get方法直接访问servlet,找不到servlet类,报异常java.lang.classnotfoundexception和404错误问题
- 2017.10.31问题总结