java网络流最大流代码 java 网络流

java httpserveletresponse文件流最大是多少

ServletResponse中定义了如下两个方法

专业成都网站建设公司,做排名好的好网站,排在同行前面,为您带来客户和效益!成都创新互联公司为您提供成都网站建设,五站合一网站设计制作,服务好的网站设计公司,网站设计、成都网站建设负责任的成都网站制作公司!

getOutputStream();

getWriter();

对应获得字节流和字符流

由于HttpServletResponse继承自ServletResponse所以天生也具有以上两个获得输出流的方法

怎么样求网络的最大流和最小截集

首先是网络流中的一些定义:

V表示整个图中的所有结点的集合.

E表示整个图中所有边的集合.

G = (V,E) ,表示整个图.

s表示网络的源点,t表示网络的汇点.

对于每条边(u,v),有一个容量c(u,v) (c(u,v)=0),如果c(u,v)=0,则表示(u,v)不存在在网络中。相反,如果原网络中不存在边(u,v),则令c(u,v)=0.

对于每条边(u,v),有一个流量f(u,v).

一个简单的例子.网络可以被想象成一些输水的管道.括号内右边的数字表示管道的容量c,左边的数字表示这条管道的当前流量f.

网络流的三个性质:

1、容量限制: f[u,v]=c[u,v]

2、反对称性:f[u,v] = - f[v,u]

3、流量平衡: 对于不是源点也不是汇点的任意结点,流入该结点的流量和等于流出该结点的流量和。

只要满足这三个性质,就是一个合法的网络流.

最大流问题,就是求在满足网络流性质的情况下,源点 s 到汇点 t 的最大流量。

求一个网络流的最大流有很多算法 这里首先介绍 增广路算法(EK)

学习算法之前首先看了解这个算法中涉及到的几个图中的定义:

**残量网络

为了更方便算法的实现,一般根据原网络定义一个残量网络。其中r(u,v)为残量网络的容量。

r(u,v) = c(u,v) – f(u,v)

通俗地讲:就是对于某一条边(也称弧),还能再有多少流量经过。

Gf 残量网络,Ef 表示残量网络的边集.

这是上面图的一个残量网络。残量网络(如果网络中一条边的容量为0,则认为这条边不在残量网络中。

r(s,v1)=0,所以就不画出来了。另外举个例子:r(v1,s) = c(v1,s) – f(v1,s) = 0 – (-f(s,v1)) = f(s,v1) = 4.

其中像(v1,s)这样的边称为后向弧,它表示从v1到s还可以增加4单位的流量。

但是从v1到s不是和原网络中的弧的方向相反吗?显然“从v1到s还可以增加4单位流量”这条信息毫无意义。那么,有必要建立这些后向弧吗?

显然,第1个图中的画出来的不是一个最大流。

但是,如果我们把s - v2 - v1 - t这条路径经过的弧的流量都增加2,就得到了该网络的最大流。

注意到这条路径经过了一条后向弧:(v2,v1)。

如果不设立后向弧,算法就不能发现这条路径。

**从本质上说,后向弧为算法纠正自己所犯的错误提供了可能性,它允许算法取消先前的错误的行为(让2单位的流从v1流到v2)

注意,后向弧只是概念上的,在程序中后向弧与前向弧并无区别.

**增广路

增广路定义:在残量网络中的一条从s通往t的路径,其中任意一条弧(u,v),都有r[u,v]0。

如图绿色的即为一条增广路。

看了这么多概念相信大家对增广路算法已经有大概的思路了吧。

**增广路算法

增广路算法:每次用BFS找一条最短的增广路径,然后沿着这条路径修改流量值(实际修改的是残量网络的边权)。当没有增广路时,算法停止,此时的流就是最大流。

**增广路算法的效率

设n = |V|, m = |E|

每次增广都是一次BFS,效率为O(m),而在最坏的情况下需要(n-2增广。(即除源点和汇点外其他点都没有连通,所有点都只和s与t连通)

所以,总共的时间复杂度为O(m*n),所以在稀疏图中效率还是比较高的。

hdoj 1532是一道可以作为模板题目练手。

模板代码:

[cpp] view plain copy print?

#include cstdio

#include cstring

#include iostream

#include string

#include algorithm

#include map

#include vector

using namespace std;

const int N = 1100;

const int INF = 0x3f3f3f3f;

struct Node

{

int to;//终点

int cap; //容量

int rev; //反向边

};

vectorNode v[N];

bool used[N];

void add_Node(int from,int to,int cap) //重边情况不影响

{

v[from].push_back((Node){to,cap,v[to].size()});

v[to].push_back((Node){from,0,v[from].size()-1});

}

int dfs(int s,int t,int f)

{

if(s==t)

return f;

used[s]=true;

for(int i=0;iv[s].size();i++)

{

Node tmp = v[s][i]; //注意

if(used[tmp.to]==false tmp.cap0)

{

int d=dfs(tmp.to,t,min(f,tmp.cap));

if(d0)

{

tmp.cap-=d;

v[tmp.to][tmp.rev].cap+=d;

return d;

}

}

}

return 0;

}

int max_flow(int s,int t)

{

int flow=0;

for(){

memset(used,false,sizeof(used));

int f=dfs(s,t,INF);

if(f==0)

return flow;

flow+=f;

}

}

int main()

{

int n,m;

while(~scanf("%d%d",n,m))

{

memset(v,0,sizeof(v));

for(int i=0;in;i++)

{

int x,y,z;

scanf("%d%d%d",x,y,z);

add_Node(x,y,z);

}

printf("%d\n",max_flow(1,m));

}

}

最大网络流问题 ,谁能帮我把题目的代码写一下,用c++或c写。题目如下:

#includeiostream

#includequeue

using namespace std;

#define INF 1000000000

struct node{

int from;

int to;

int flow;

}f[1000];

int n,m;

int maxf[1000];

bool vis[1000];

void bfs()

{

queueint p;

int i;

vis[1]=true;

p.push(1);

while(!p.empty())

{

int q=p.front();

p.pop();

for(i=1;i=m;i++)

{

if(f[i].from==q)

{

if(vis[f[i].to]==0)

{

p.push(f[i].to);

vis[f[i].to]=true;

}

maxf[f[i].to]+=min(f[i].flow,maxf[q]);

}

}

}

coutmaxf[n]endl;

}

int main()

{

while(cinnm)

{

int i;

for(i=1;i=m;i++)

{

cinf[i].fromf[i].tof[i].flow;

}

memset(maxf,0,sizeof(maxf));

memset(vis,0,sizeof(vis));

maxf[1]=INF;

bfs();

}

return 0;

}

BFS解最大流。

网络流的最大流算法

1、augment path,直译为“增广路径”,其思想大致如下:

原有网络为G,设有一辅助图G',其定义为V(G') = V(G),E(G')初始值(也就是容量)与E(G)相同。每次操作时从Source点搜索出一条到Sink点的路径,然后将该路径上所有的容量减去该路径上容量的最小值,然后对路径上每一条边u,v添加或扩大反方向的容量,大小就是刚才减去的容量。一直到没有路为止。此时辅助图上的正向流就是最大流。

我们很容易觉得这个算法会陷入死循环,但事实上不是这样的。我们只需要注意到每次网络中由Source到Sink的流都增加了,若容量都是整数,则这个算法必然会结束。

寻找通路的时候可以用DFS,BFS最短路等算法。就这两者来说,BFS要比DFS快得多,但是编码量也会相应上一个数量级。

增广路方法可以解决最大流问题,然而它有一个不可避免的缺陷,就是在极端情况下每次只能将流扩大1(假设容量、流为整数),这样会造成性能上的很大问题,解决这个问题有一个复杂得多的算法,就是预推进算法。

2、push label,直译为“预推进”算法。

3、压入与重标记(Push-Relabel)算法

除了用各种方法在剩余网络中不断找增广路(augmenting)的Ford-Fulkerson系的算法外,还有一种求最大流的算法被称为压入与重标记(Push-Relabel)算法。它的基本操作有:压入,作用于一条边,将边的始点的预流尽可能多的压向终点;重标记,作用于一个点,将它的高度(也就是label)设为所有邻接点的高度的最小值加一。Push-Relabel系的算法普遍要比Ford-Fulkerson系的算法快,但是缺点是相对难以理解。

Relabel-to-Front使用一个链表保存溢出顶点,用Discharge操作不断使溢出顶点不再溢出。Discharge的操作过程是:若找不到可被压入的临边,则重标记,否则对临边压入,直至点不再溢出。算法的主过程是:首先将源点出发的所有边充满,然后将除源和汇外的所有顶点保存在一个链表里,从链表头开始进行Discharge,如果完成后顶点的高度有所增加,则将这个顶点置于链表的头部,对下一个顶点开始Discharge。

Relabel-to-Front算法的时间复杂度是O(V^3),还有一个叫Highest Label Preflow Push的算法复杂度据说是O(V^2*E^0.5)。我研究了一下HLPP,感觉它和Relabel-to-Front本质上没有区别,因为Relabel-to-Front每次前移的都是高度最高的顶点,所以也相当于每次选择最高的标号进行更新。还有一个感觉也会很好实现的算法是使用队列维护溢出顶点,每次对pop出来的顶点discharge,出现了新的溢出顶点时入队。

Push-Relabel类的算法有一个名为gap heuristic的优化,就是当存在一个整数0kV,没有任何顶点满足h[v]=k时,对所有h[v]k的顶点v做更新,若它小于V+1就置为V+1。

cpp程序: #includecstdio#includecstring#includealgorithm#includequeue#define inf 0x7fffffffusingnamespace std;int tt,kase;int nn,m;int H[45],X[1004],P[1004],flow[1004],tot,cap[1005];int d[45];int S,T;void add(int x,int y,int z){P[++tot]=y;X[tot]=H[x];H[x]=tot;flow[tot]=z;cap[tot]=flow[tot];}queueint q;bool bfs(){memset(d,0,sizeof(d));d[S]=1; int x;q.push(S);while(!q.empty()){x=q.front();q.pop();for(int i=H[x];i;i=X[i]){if(flow[i]0!d[P[i]]){d[P[i]]=d[x]+1;q.push(P[i]);}}}returnd[T];}int dfs(int x,int a){if(x==T||a==0)return a;int f=a,tmp;for(int i=H[x];i;i=X[i]){if(flow[i]0d[P[i]]==d[x]+1){tmp=dfs(P[i],min(flow[i],a));flow[i]-=tmp;a-=tmp;flow[i^1]+=tmp;if(!a)break;}}if(f==a)d[x]=-1;return f-a;}int Dinic(){int f=0;while(bfs())f+=dfs(S,inf);return f;}int main(){/**输入过程省略**/int maxflow=Dinic();printf(%d\n,maxflow);return 0;}

网站标题:java网络流最大流代码 java 网络流
网站链接:https://www.cdcxhl.com/article46/ddeephg.html

成都网站建设公司_创新互联,为您提供服务器托管微信小程序网站改版网站内链品牌网站制作网站维护

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

营销型网站建设