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

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

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

#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[N].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 6 2
5 6 4
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 6 8
5 6 4
6
8
1 2 2
1 3 7
2 4 3
2 5 4
3 4 4
3 5 2 
4 6 1
5 6 5
 
 

下面是out.txt的输出结果,如下

One of the path is :6 from 5 from 2 from 1 and the flow is 2
One of the path is :6 from 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 :6 from 5 from 2 from 1 and the flow is 2
One of the path is :6 from 4 from 2 from 1 and the flow is 3
One of the path is :6 from 4 from 3 from 1 and the flow is 3
One of the path is :6 from 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 :6 from 4 from 2 from 1 and the flow is 1
One of the path is :6 from 5 from 2 from 1 and the flow is 1
One of the path is :6 from 5 from 3 from 1 and the flow is 2
One of the path is :6 from 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).


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值