graph里面的相关知识点(未完)

所有的代码都没有运行过,大意表示出来即可。(可能以后会补充出来)

1 两个搜索和遍历 DFS和BFS

int pre[800];
queue<graph> Q;
stack<graph> S;
void BFS(graph G,int v)//从v开始入队
{
 int i;
 Q.push(v);
 pre[v]=cnt++;//prev[]数组记录的是访问次序
 while(!Q.empty()){
  i=Q.front();
  Q.pop();
  for(j=0;j<G->n;j++)
  if(G->a[i][j]&&(per[j]==0))
  {
   Q.push(j);
   pre[j]=cnt++;
  }
 }
}
//广度优先遍历
//每一次遍历都能访问图的一个连通分支,要想访问所有的连通分支那就把所有的顶点
 //都访问一遍
void BFS_traverse(graph G)
{
 for(i=0;i<G->n;i++)
 pre[i]=0;//初始化
 for(i=0;i<G->n;i++){
  if(pre[i]==0) //若pre[i]!=0意味着还未被访问过,pre[i]可以用来记录访问的次序
  BFS(i);
 }
}
//类似的可以写出DFS以及DFS_traverse
//并且有递归和非递归的两种形式,也就是显示和引式的使用栈
void DFS(graph G,int v)
{
 int i;
 pre[v]=cnt++;
 for(j=0;j<G->n;j++){ //邻接表只要将这里改为p,p=p->next
  if(G->a[i][j]&&pre[j]==0){
   DFS(G,j);
  }
 }
}
void DFS_traverse(graph G)
{
 int i;
 int cnt=1;
 for(i=0;i<G->n;i++){
  pre[i]=0;
 }
 for(i=0;i<G->n;i++){
  if(pre[i]==0)
  DFS(G,i);
 }
}
最短路径问题
2 单源最短路径问题
 1 不带负权 Dijktral
利用贪心算法,newdist=c[u][j]+dist[u];其实重点就是比较这两个东西
 2 带负权 bellman ford算法
核心代码
for(i=1;i<=nodenum-1;i++){  //除源点外至多经历nodenum-1次
  for(j=1;j<=edgenum;j++)//每一次每条边都检测过去
  if(dist[Edge[j].v]>dist[Edge[j].u]+Edge[j].weight){
   dist[Edge[j].v] = dist[Edge[j].u]+Edge[j].weight;
   prev[Edge[j].v] = Edge[j].u;
  }
 }
3 多源最短路径
或者也是利用n次的Dijktra算法
floyd算法
void floyd(){
 rep(k,1,n+1)rep(i,1,n+1)rep(j,1,n+1){
  e[i][j] = min(e[i][j],e[i][k]+e[k][j]);
 }
}
核心也就是三重循环

最小生成树问题
MST
1 prim算法以及克鲁斯卡尔算法

//图匹配问题以及求最大匹配问题
//利用匈牙利算法,通过增广矩阵实现最大匹配问题

//拓扑排序
//如果拓扑排序的结果唯一,那么该拓扑排序的结果同时也代表了一条哈密顿路径。
//理解有关全序的概念
void tuopu_sort(graph G)
{
 //计算每个顶点的入度
 //可以用栈来存储
 stack<int> s;
 int i;
 Node *temp;
 for(i=0;i<G->n;i++){
  temp=arc[i].first;
  while(temp){
   indegree[temp->index]++;
   temp=temp->next;
  }
 }
 
 //把入度为0的点入栈
 for(i=0;i<G->n;i++){
  if(!indegree[i]){
   s.push(i);
  }
 }
 
 //用count来计数能不能拓扑排序
 int count=0;
 while(!s.empty()){
  i=s.top();//将栈顶顶点记录下来
  s.pop();
  //与I 有关的顶点的入度数全部相应的改变
  cout<<"出度为"<<i<<" ";
  temp=arc[i].fisrtneighbour;
  while(temp){
   if(!(--indegree[temp->index])){
    s.push(temp->index);
    temp=temp->next;
   }
  }
  count++;
 }
 if(count==G->n) {
  cout<<endl;
  cout<<"可以进行拓扑排序"<<endl;
 }
 else cout<<"仍有剩余顶点"<<endl;
}
//2 利用DFS隐式的利用递归
void DFS(int n,bool visit[],stack<int> result)
{
 visit[n]=1;
 Node *temp=G->firstneightbour;
 while(temp){
  if(!visit[temp->index]){
   DFS(G->n,visit,result);
  }
  temp=temp->next;
 }
}
void tuopu_sort2(Graph G)
{
 stack<int> result;
 bool *visit = new bool [G->n];
 memset(visit,0,n);
 //DFS算法如下
 for(int i=0;i<G->n;i++){
  if(!visit[i]){
   DFS(i,visit,result);
  }
 }
 //每次都是找入度为0的点,输出时也要逆序输出
 for(i=0;i<G->n;i++){
  cout<<result.top<<" ";
  result.pop();
 }
}

先罗列相关知识点,代码后续补充。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值