您的位置:首页 > 编程语言 > C语言/C++

最大流与最小割C++实现2——深度优先搜索

2014-03-13 16:17 519 查看
         刚刚写了一个最大流与最小割的的广度优先搜索实现!后来我发现只要用栈来替代队列来储存标记的顶点,便实现了深度优先搜索.

但要注意此时应该先把后向边压入栈!以下是我的代码实现:

#include<iostream>
#include<stack>
#include<vector>
#include<cmath>
#include<stdio.h>
#define MAX 999999
using namespace std;

class Graph
{
private:
struct vertex
{
int num ; //编号
int flag ; //正向或负向标记
int ver ; //来自哪条边
int flow; //流量标记
vector<int>f_edge ; //前向边
vector<int>u ; //前向边的流量
vector<int>b_edge; //后向边
vector<int>x ; //后向边的流量
vertex(int num,int flag,int flow):num(num),flag(flag),flow(flow){ // u.push_back(0); x.push_back(0);
}
};
int N; //边数
vector<vertex>v;
public:
Graph(int n):N(n)
{
for(int i=0;i<=n;i++)
{
vertex tmp(i,0,0);
v.push_back(tmp);
for(int j=0;j<=n;j++)
{
v[i].u.push_back(0);
v[i].x.push_back(0);
}
}

v[1].flag=-1; //源点标记为-1
v[1].flow=MAX;

}
void Edge_flow(int i,int j,int flow)
{ v[i].f_edge.push_back(j);
v[i].u[j]=flow;
v[j].b_edge.push_back(i);
}
int Max_flow()
{

stack<int>S;
S.push(1);
int max_f=0;
while(!S.empty())
{
int i=S.top();S.pop();
int l=v[i].flow;
for(unsigned int k=0;k<v[i].b_edge.size();k++)
{
int j=v[i].b_edge[k];
if(v[j].flag==0)
{
int r=v[j].x[i];
if(r>0)
{
l=min(l,r);
v[j].flag=-1;v[j].ver=i;v[j].flow=l;
S.push(j);
}
}
}
for(unsigned int k=0;k<v[i].f_edge.size();k++)
{
int j=v[i].f_edge[k];
if(v[j].flag==0)
{

int r=v[i].u[j]-v[i].x[j];
if(r>0)
{
l=min(l,r);
v[j].flag=1;v[j].ver=i;v[j].flow=l;
S.push(j);
}
}
}

if(v
.flag!=0)
{
int j=N;
max_f+=l;
cout<<"One of the path is :";
while(j!=1)
{
cout<<j<<" from ";
int k=v[j].ver;
if(v[j].flag==1)
v[k].x[j]+=l;
if(v[j].flag==-1)
v[j].x[k]-=l;
j=k;
}
cout<<1<<" and the flow is "<<l<<endl;
while(!S.empty())
S.pop();
for(int i=2;i<=N;i++)
v[i].flag=0;
S.push(1);
}

}
return max_f;

}
void Min_cut()
{
for(int i=1;i<N;i++)
{
if(v[i].flag!=0)
{
for(unsigned int k=0;k<v[i].f_edge.size();k++)
{
int j=v[i].f_edge[k];
if(v[j].flag==0&&v[i].flag!=0)
cout<<"("<<i<<","<<j<<")"<<"; ";
}
}
}

}

};
int main()
{
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int ver;
while(cin>>ver)
{
Graph G(ver);
int edge;
cin>>edge;
int i,j,flow;
while(edge--)
{
cin>>i>>j>>flow;
G.Edge_flow(i,j,flow);
}
cout<<"The max_flow is :"<<G.Max_flow()<<endl;
cout<<"One of the min_cut is :";
G.Min_cut();
cout<<endl;
}
fclose(stdin);
// fclose(stdout);
return 0;
}


接下来是in.txt里的测试数据,如下:
6

7

1 2 2

1 4 3

2 5 3

2 3 5

4 3 1

3 62

5 64

4

5

1 2 100

1 3 10

2 3 100

3 4 10

2 4 1000

6

7

1 2 5

1 3 6

2 5 2

2 4 4

3 4 7

4 68

5 64

6

8

1 2 2

1 3 7

2 4 3

2 5 4

3 4 4

3 5 2

4 61

5 65




下面是out.txt的输出结果,如下
One of the path is :6from 5 from 2 from 1 and the flow is 2

One of the path is :6from 3 from 4 from 1 and the flow is 1

The max_flow is :3

One of the min_cut is :(1,2);  (4,3); 

One of the path is :4 from 2 from 1 and the flow is 100

One of the path is :4 from 3 from 1 and the flow is 10

The max_flow is :110

One of the min_cut is :(1,2);  (1,3); 

One of the path is :6from 5 from 2 from 1 and the flow is 2

One of the path is :6from 4 from 2 from 1 and the flow is 3

One of the path is :6from 4 from 3 from 1 and the flow is 3

One of the path is :6from 4 from 3 from 1 and the flow is 2

The max_flow is :10

One of the min_cut is :(2,5);  (4,6); 

One of the path is :6from 4 from 2 from 1 and the flow is 1

One of the path is :6from 5 from 2 from 1 and the flow is 1

One of the path is :6from 5 from 3 from 1 and the flow is 2

One of the path is :6from 5 from 2 from 4 from 3 from 1 and the flow is 1

The max_flow is :5

One of the min_cut is :(1,2);  (3,5);  (4,6);


可以看到,测试数据也是没有问题的,这说明我的这种替代是合理的;再根据分析,深度优先搜索效率也是O(nm^2)的,空间消耗是O(n^2).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息