图算法《c++算法》(二)

// d路堆
#ifndef PQI_INCLUDE_H
#define  PQI_INCLUDE_H
#include 
< vector >
using  std::vector;
template 
< class  keyType >
class  PQi
{
private:
    
int d;
    
int N;
    vector
<int>p, q;
    
const vector<keyType>&a;
public:
    PQi(
int N, const vector<keyType>&a, int d = 3):a(a),p(N+10),
        q(N
+10),N(0),d(d){   }
    
int  empty()const;
    
void exch(int i, int j);
    
void fixUp(int k);
    
void fixDown(int k, int N);
    
void insert(int v);
    
int  getmin();
    
void lower(int k);
}
;
#endif
#ifndef INSTANCE_PQI_INCLUDE
#define  INSTANCE_PQI_INCLUDE
#include 
" PQi.h "
template
< class  keyType >
void  PQi < keyType > ::exch( int  i,  int  j)
{
    
int t = p[i];
    p[i] 
= p[j];
    p[j] 
= t;
    q[p[i]] 
= i;
    q[p[j]] 
= j;
}

template
< class  keyType >
void  PQi < keyType > ::fixUp( int  k)
{
    
while (k > 1 && a[p[(k+d-2)/d]] > a[p[k]])
    
{
      exch(k, (k
+d-2)/d);
      k 
= (k+d-2)/d;
    }

}

template
< class  keyType >
void   PQi < keyType > ::fixDown( int  k,  int  N)
{
    
int j;
    
while((j = d*(k-1+ 2<= N)
    
{
        
for(int i = j+1; i < j+&& j <= N; i++)
        
if(a[p[j]] > a[p[i]]) j = i;
        
if(!(a[p[k]] > a[p[j]])) break;
        exch(k, j);
        k 
= j;
    }

}

template
< class  keyType >
void  PQi < keyType > ::insert( int  v)
{
        p[
++N] = v;
        q[v] 
= N;
        fixUp(N);
}

template
< class  keyType >
int  PQi < keyType > ::getmin()
{
        exch(
1, N);
        fixDown(
1, N-1);
        
return p[N--];
}

template
< class  keyType >
int  PQi < keyType > ::empty() const  

    
return N == 0;
}

template
< class  keyType >
void  PQi < keyType > ::lower( int  k)
{
    fixUp(q[k]); 
}


#endif
//  Densegraph__.cpp : Defines the entry point for the console application.
// SPT(单源最短路径):给定一个起始顶点s,找到s到图中的其他各顶点的最短路径。
// 全源最短路径:找出连接图中各对顶点的最短路径。
// MST:最小生成树,权值最小的树。
// 关于权值:权值最好是0——1之间,这样更具有通用性,即使权值不为零,也可以同时缩小多少倍,
//  比如1/10, 1/100, 1/1000,1/10000等,视最大值的情况而定。
#include  " stdafx.h "
#include 
< iostream >
#include 
< string >
#include 
< vector >
#include 
" PQi.h "
#include 
" PQi_INS.H "
using   namespace  std;

class  DenseGraph
{
private:
    
struct Edge
    
{   
        Edge(
int vv, int ww , double wt):v(vv),w(ww),weight(wt){ }
        
int  v;
        
int  w;
        
double  weight;
    }
;
    
int Vcnt;
    
int Ecnt;
    
bool digraph;//判断是不是有向图
    vector<vector<Edge*> >adj;
    
int i;
    
int v;
    vector
<double> wt;
    vector
<Edge*>fr, mst;
    vector
<Edge* > spt;
    vector
<vector<Edge*> >p;
    vector
<vector<double> >d;
    Edge
* ftr[15];
    
int count;

public:
    DenseGraph(
int V, bool digraph_ = false)
    
{  
        Edge(
000);
        Vcnt 
= V;
        Ecnt 
= 0;
        digraph 
= digraph_;
        adj.resize(V, vector
<Edge*>(V,0) );
        i 
= 0;
        v 
= V;
        wt.resize(V, V);
        fr.resize(V, 
0);
        mst.resize(V, 
0);
        spt.resize(V, 
0);
        p.resize(V, vector
<Edge* >(V,0) );
        d.resize(V, vector
<double>(V,V) );
        
for(int f = 0; f < 15; f++)
            ftr[f] 
= 0;
        count 
= -1;
        
    }

 
int V() const return Vcnt; }
 
int E() const return Ecnt; }
 
bool directed() const return digraph; }
 
void insert(Edge* e)
 
{   
    
    
int v = e->v;
    
int w = e->w;
    
if(0 == adj[v][w])
    
{
        Ecnt
++;
        adj[v][w] 
= e;
    }

    
if(!digraph)
    
{
        adj[w][v] 
= e;
    }

 }

 
void remove(int v, int w)
 
{
    
   
if(0 != adj[v][w])
   
{
       Ecnt
--;
       adj[v][w] 
= 0;
   }

   
if(!digraph)
   
{
     adj[w][v] 
= 0;
   }

 }


Edge
* edge(int v, int w)  
{  
     
if(0 != adj[v][w])
     
{
         
return adj[v][w];
     }

     
else
     
{
          
return 0;
     }

    
}


Edge
* Begin(){ i = -1return Next(); }
Edge
* Next()
{
    
for(i++; i < V(); i++)
    
{
    
        
if(edge(v, i))
        
return adj[v][i];
    }


}

bool End() const return i >= V(); }

void MST_Prim()
{
    
int min = -1;
    
for(int v = 0; min != 0; v = min)
    
{  
        min 
= 0;
        
//w循环找出最小边,与此同时(如果w不在MST上)还会维护循环不变式,
        
//即边fr[w]是从w到MST的最短边(权值为wt[w]).
        for(int w = 1; w < V(); w++)
        
{
            
if(0 == mst[w])//mst[w]记录已经在MST中的点
            {
                
double p = 0;
                Edge
* e = edge(v, w);
                
if(e)
                
                    
if((p = e->weight)< (wt[w]))
                    
{
                        wt[w] 
= p;
                        fr[w] 
= e;
                    }

                    
if(wt[w] < wt[min] ) min = w;
                    
//第一:如果边存在,记录最小的边。
                   
//第二:如果边不存在,比如举例所示的点2,他没有到其他点的边,
            }
     //那么从边缘带中找出权值离0的最小边,继续比较。
        }

        
if(min)
        
{
          mst[min] 
= fr[min];//记录各点在MST中
          cout<<min<<"--";
        }

    }

}

//不能用于负边,而且是用于有向树,求s到每个点的最短路径。
//Dijkstra算法:一次增加一条边以扩展SPT,每一次要更新对于与该边结束顶点相邻接的所有顶点
//到达树的距离,与此同时还要检查所有非树顶点以找出一条边从而将其移到树种,此边的目的顶点是一个
//非树顶点,而且与源点有最小的距离。
//wt中保存着从源点到其他顶点的已知最短路径
//spt记录从源点到索引顶点的最短路径的最后一条边。
//边松弛:检查沿着一条给定的边是否可以给出到达其目的顶点的一条新的路径
//if(wt[w] > wt[v] + e ->weight){ wt[w] = wt[v] + e->weight; spt[w] = e; }

void SPT_Dijkstra(int s)
{
    PQi
<double>PQ(V(), wt);
    
for(v = 0; v < V()-1; v++)
    PQ.insert(v);
    wt[s] 
= 0;
    PQ.lower(s);
    
while(!PQ.empty())
    
{
        
int v = PQ.getmin();
        
if(v != s && 0 == spt[v]) return;
        
for(Edge* e = Begin(); !End(); e = Next())
        
{
            
int w = e->w;
            
double P = wt[v] + e->weight;
            
if(P < wt[w])
            
{
                wt[w] 
= P;
                PQ.lower(w);
                spt[w] 
= e;
            }

        }

    }

}


Edge
* pathR(int v) const return spt[v]; }
double dist(int v) const return wt[v]; }
 
//全源最短路径的floyd算法
//路径松弛:检查通过一个给定顶点是否可以给出连接另外两个给定顶点的一条最新的最短路径。
//if(d[s][t] > d[s][x] + d[x][t]){d[s][t] = d[s][x] + d[x][t]; p[s][t] = p[s][x]; }

void AllPath_Floyd()
{
    
int Vl = V();
   
for(int s = 0; s < Vl; s++)
    
{
        
for(int t = 0; t < Vl; t++)
        
{
            
if(edge(s, t))
            
{
                
                p[s][t] 
= edge(s, t);
                d[s][t] 
= edge(s, t)->weight;
            }

        }
   
    }

  
for(s = 0; s < Vl; s++) d[s][s] = 0;
        
  
for(i = 0; i < Vl; i++)
  
{
    
for(int s = 0; s < Vl; s++)
    
{
        
if(p[s][i])
        
{
            
for(int t = 0; t < Vl; t++)
            
{
                
if( s != t)
                
{
                    
if(d[s][t] > d[s][i] + d[i][t])
                    
{
                        p[s][t] 
= p[s][i];
                        d[s][t] 
= d[s][i] + d[i][t];
                    }

                }

            }

        }

    }

  }

    
}


Edge
* adapter_insert(int x, int y, double z)
 
{
    
      
++count;
      ftr[count] 
= new Edge(x, y, z);

      
return ftr[count];
 }




 
~DenseGraph()
 

     
for(int i = 0; i < V(); i++)
       delete ftr[i];
 }



}
;


int  main( int  argc,  char *  argv[])
{   
    
//DenseGraph oop(15);
    /*(oop.insert(oop.adapter_insert(0, 2, 0.29));
    oop.insert(oop.adapter_insert(0, 6, 0.34));
    oop.insert(oop.adapter_insert(0, 7, 0.31));
    oop.insert(oop.adapter_insert(0, 1, 0.32));
    oop.insert(oop.adapter_insert(0, 5, 0.53));
    oop.insert(oop.adapter_insert(1, 7, 0.21));
    oop.insert(oop.adapter_insert(7, 6, 0.25));
    oop.insert(oop.adapter_insert(7, 4, 0.46));
    oop.insert(oop.adapter_insert(6, 4, 0.50));
    oop.insert(oop.adapter_insert(3, 4, 0.34));
    oop.insert(oop.adapter_insert(3, 5, 0.18));
    oop.insert(oop.adapter_insert(5, 4, 0.40));
    
*/

     
//////////////////////////////////
     //cout<<oop.edge(0,2)->weight<<endl;
     
//cout<<oop.edge(0,6)->weight<<endl;
     
//cout<<oop.edge(0,7)->weight<<endl;
     
//cout<<oop.edge(0,1)->weight<<endl;
     
//cout<<oop.edge(0,5)->weight<<endl;
     
//cout<<oop.edge(1,7)->weight<<endl;
     
//cout<<oop.edge(7,6)->weight<<endl;
     
//cout<<oop.edge(7,4)->weight<<endl;
     
//cout<<oop.edge(6,4)->weight<<endl;
     
//cout<<oop.edge(3,4)->weight<<endl;
     
//cout<<oop.edge(3,5)->weight<<endl;
     
//cout<<oop.edge(5,4)->weight<<endl;
     ////////////////////////////////////
     //oop.MST_Prim();
    
//oop.SPT_Dijkstra(5);
    DenseGraph oop(15true);//有向树
    oop.insert(oop.adapter_insert(020.29));
    oop.insert(oop.adapter_insert(
060.34));
    oop.insert(oop.adapter_insert(
070.31));
    oop.insert(oop.adapter_insert(
010.32));
    oop.insert(oop.adapter_insert(
050.53));
    oop.insert(oop.adapter_insert(
170.21));
    oop.insert(oop.adapter_insert(
760.25));
    oop.insert(oop.adapter_insert(
740.46));
    oop.insert(oop.adapter_insert(
640.50));
    oop.insert(oop.adapter_insert(
340.34));
    oop.insert(oop.adapter_insert(
350.18));
    oop.insert(oop.adapter_insert(
540.40));
    oop.SPT_Dijkstra(
5);
     
return 0;
}


 

你可能感兴趣的:(C++,算法,vector,Class,insert,include)