您的位置:首页 > 理论基础 > 计算机网络

模板_网络流

2016-01-08 19:11 519 查看
首先来一个简单的EdmondsKarp算法,跟SPFA很像,BFS找最短路

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<climits>
#include<iostream>
using namespace std;
#define N 205
struct Edge{
int fr,to,cap,flow;
Edge(int u,int v,int c,int f):fr(u),to(v),cap(c),flow(f){}
};
struct EdmondsKarp{
int n,m;
vector<Edge> edges;
vector<int> G
;
int a
,p
;
void init(int n){
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void Add_Edge(int fr,int to,int cap){
edges.push_back(Edge(fr,to,cap,0));
edges.push_back(Edge(to,fr,0,0));
m=edges.size();
G[fr].push_back(m-2);
G[to].push_back(m-1);
}
int Max_Flow(int s,int t){
int flow=0;
for(;;){
memset(a,0,sizeof(a));
queue<int> Q;
Q.push(s);
a[s]=INT_MAX;
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=0;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(!a[e.to]&&e.cap>e.flow){
p[e.to]=G[x][i];
a[e.to]=min(a[x],e.cap-e.flow);
Q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u=t;u!=s;u=edges[p[u]].fr){
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
}
flow+=a[t];
}
return flow;
}
}f;


唔……再来一个费用流吧

算法主体

int spfa(){
int s=hash(1,1)*2,t=hash(n,n)*2+1,x;
queue<int> q;int b[N*N];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
d[hash(i,j)*2]=INF,b[hash(i,j)*2]=false;
d[hash(i,j)*2+1]=INF,b[hash(i,j)*2+1]=false;
}
b[s]=true,d[s]=0,a[s]=1;q.push(s);
while(!q.empty()){
x=q.front();q.pop();b[x]=false;
for(int i=0;i<g[x].size();i++){
Edge& e=edge[g[x][i]];
if(e.cap>e.flow&&d[e.to]>d[x]+e.cost){
d[e.to]=d[x]+e.cost;
p[e.to]=g[x][i];
a[e.to]=min(a[x],e.cap-e.flow);
if(!b[e.to])    {b[e.to]=true;q.push(e.to);}
}
}
}
if(d[t]==INF) return 0;
ans+=d[t]*a[t];
for(x=t;x!=s;x=edge[p[x]].fr){
edge[p[x]].flow+=a[t],edge[p[x]^1].flow-=a[t];
}
return 1;
}


最大流的高效算法Dinic算法,BFS建层次图,DFS找增广路,递归算法

bool bfs(){
memset(d,-1,sizeof(d));memset(b,0,sizeof(b));
queue<int> q;int x;d[S]=0;b[S]=true;q.push(S);
while(!q.empty()){
x=q.front();q.pop();
for(int i=0;i<g[x].size();i++){
Edge &e=edge[g[x][i]];
if(!b[e.to]&&e.cap>e.flow){
b[e.to]=true;d[e.to]=d[x]+1;q.push(e.to);
}
}
}
return b[T];
}

int dfs(int x,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=edge[g[x][i]];
if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
e.flow+=f;edge[g[x][i]^1].flow-=f;
flow+=f;a-=f;
if(a==0) break;
}
}
return flow;
}

void Max_Flow(){
flow=0;
while(bfs()){
memset(cur,0,sizeof(cur));
flow+=dfs(S,INF);
}
}


Dinic算法的非递归实现

bool bfs(){
memset(d,-1,sizeof(d));memset(b,0,sizeof(b));
queue<int> q;int x;d[S]=0;b[S]=true;q.push(S);
while(!q.empty()){
x=q.front();q.pop();
for(int i=0;i<g[x].size();i++){
Edge &e=edge[g[x][i]];
if(!b[e.to]&&e.cap>e.flow){
b[e.to]=true;d[e.to]=d[x]+1;q.push(e.to);
}
}
}
return b[T];
}
void Max_Flow(){
flow=0;
while(bfs()){
int k=0,x=S;
memset(cur,0,sizeof(cur));
for(;;){
if(x==T){
int mine=-1,minf=INF;
for(int i=0;i<k;i++)
if(edge[p[i]].cap-edge[p[i]].flow<minf){
minf=edge[p[i]].cap-edge[p[i]].flow;
mine=i;
}
for(int i=0;i<k;i++){
edge[p[i]].flow+=minf;
edge[p[i]^1].flow-=minf;
}
k=mine;x=edge[p[mine]].fr;flow+=minf;
}
for(int &i=cur[x];i<g[x].size();i++){
Edge &e=edge[g[x][i]];
if(e.cap>e.flow&&d[x]+1==d[e.to]) break;
}
if(cur[x]<g[x].size()){
p[k++]=g[x][cur[x]];
x=edge[g[x][cur[x]]].to;
}
else{
if(k==0) break;
d[x]=-1;k--;x=edge[p[k]].fr;
}
}
}
}


最后比较神的算法,缩点全局最小割Stoer-Wagner

#include<cstdio>
#include<climits>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
#define N 505
#define INF INT_MAX/3*2
struct Min_Cut{
struct Dist{
int s,d;
/*  Dist(int a,int b):s(a),d(b){}
bool operator <(const Dist &b)const{
if(d==b.d) return s>b.s;
return d<b.d;
}*/
};
int mp

;bool use
;
int n,m,ans,S,T;

int in(){
int x=0;char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}

void init(){
memset(mp,0,sizeof(mp));memset(use,0,sizeof(use));
int x,y,z;ans=INF;
while(m--){
x=in(),y=in(),z=in();
mp[x][y]+=z;mp[y][x]+=z;
}
return;
}

int MinCut(int &s,int &t){
bool vis
;int w
;
memset(vis,0,sizeof(vis));memset(w,0,sizeof(w));
int tmpj=N;
for(int i=0;i<n;i++){
int max=-INF;
for(int j=0;j<n;j++){
if(!vis[j]&&!use[j]&&max<w[j]){
max=w[j];
tmpj=j;
}
}
if(t==tmpj){return w[t];}
vis[tmpj]=1;
s=t,t=tmpj;
for(int j=0;j<n;j++){
if(!vis[j]&&!use[j])
w[j]+=mp[t][j];
}
}
return w[t];
}

/*  int MinCut(int &S,int &T){
priority_queue<Dist> q;queue<Dist> p;Dist t(0,0);
for(int i=0;i<n;i++)
if(!use[i]) q.push(Dist(i,0));
while(!q.empty()){
t=q.top();q.pop();
if(T==t.s){return t.d;}
S=T;T=t.s;
while(!q.empty()){
p.push(q.top());q.pop();
}
while(!p.empty()){
t=p.front();p.pop();
q.push(Dist(t.s,mp[T][t.s]+t.d));
}
}
return q.top().d;
}*/

/*
Dist heap[N*2];int size;
void push(Dist x){
heap[++size]=x;
int now,next;now=size,next=size/2;
while(now>1){
next=now/2;
if(heap[next].d>heap[now].d) break;
else swap(heap[next],heap[now]);
now=next;
}
return;
}

Dist top(){
Dist res=heap[1];heap[1]=heap[size--];
int now,next;now=1;
while(now*2<=size){
next=now*2;
if(next+1<=size&&heap[next].d>heap[next+1].d) next++;
if(heap[now].d>heap[next].d)    break;
swap(heap[now],heap[next]);
now=next;
}
return res;
}

int MinCut(int &S,int &T){
memset(heap,0,sizeof(heap));size=0;
queue<Dist> p;Dist t;
for(int i=0;i<n;i++)
if(!use[i]){
t.s=i,t.d=0;
push(t);
}
while(size){
t=top();
if(T==t.s){return t.d;}
S=T;T=t.s;
while(size)
p.push(top());
while(!p.empty()){
t=p.front();p.pop();t.d+=mp[T][t.s];
push(t);
}
}
return top().d;
}
*/

void solve(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=1;i<n;i++){
S=T=-1;ans=min(ans,MinCut(S,T));use[T]=true;

for(int j=0;j<n;j++){
mp[S][j]+=mp[T][j];
mp[j][S]+=mp[j][T];
}
/*for(int o=0;o<n;o++){
for(int u=0;u<n;u++){
printf("%d ",mp[o][u]);
}
printf("\n");
}*/
//              printf("%d\n",ans);
}
printf("%d\n",ans);
}
return;
}
}s;
int main(){
s.solve();
return 0;
}


最后才搞得ISAP

#include<cstdio>
#include<climits>
#include<cstring>
#include<queue>
#include<vector>
#include<iostream>
using namespace std;
#define N 505
#define INF INT_MAX/3*2
struct ISAP{
struct Edge{int fr,to,flow,cap;};
vector<Edge> edge;vector<int> g
;
int p
,num
,cur
;int s,t,n;
bool v
;int d
;

void Add_Edge(int fr,int to,int flow,int cap){
edge.push_back(Edge{fr,to,flow,cap});
edge.push_back(Edge{to,fr,0,0});
g[fr].push_back(edge.size()-2);g[to].push_back(edge.size()-1);
}

int AddFlow(){
int x=t,a=INF;Edge e=edge[p[x]];
for(;x!=s;x=edge[p[x]].fr,e=edge[p[x]]) a=min(e.cap-e.flow,a);
x=t;
for(;x!=s;x=edge[p[x]].fr) edge[p[x]].flow+=a,edge[p[x]^1].flow-=a;
return a;
}

void BFS(){
for(int i=0;i<n;i++) d[i]=n;
memset(v,0,sizeof(v));
queue<int> q;int x;q.push(t);v[t]=true,d[t]=0;
while(!q.empty()){
x=q.front();q.pop();
for(int i=0;i<g[x].size();i++){
Edge &e=edge[g[x][i]];
Edge &u=edge[g[x][i]^1];
if(!v[e.to]&&u.cap>u.flow){
d[e.to]=d[x]+1;v[e.to]=true;
q.push(e.to);
}
}
}
}

int MaxFlow(){
int flow=0,x=s;BFS();
memset(num,0,sizeof(num));memset(cur,0,sizeof(cur));
for(int i=0;i<n;i++) num[d[i]]++;
while(d[s]<n){
if(x==t) flow+=AddFlow(),x=s;
int ok=0;
for(int i=cur[x];i<g[x].size();i++){
Edge &e=edge[g[x][i]];
if(e.cap>e.flow&&d[x]==d[e.to]+1){
ok=1;p[e.to]=g[x][i];
cur[x]=i;x=e.to;break;
}
}
if(!ok){
int m=n-1;
for(int i=0;i<g[x].size();i++){
Edge &e=edge[g[x][i]];
if(e.cap>e.flow) m=min(m,d[e.to]);
}
if(!(--num[d[x]])) break;
num[d[x]=m+1]++;cur[x]=0;
if(x!=s) x=edge[p[x]].fr;
}
}
return flow;
}

}s;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: