图论

存储:

1、邻接矩阵(二维数组)

2、邻接表

分为两个数组,一个存终点编号、权值、下一条下标,另一个存以i为起点,第一个终点编号:

void insert(int start,int end,int vv)

{

a[++t]=end;  

a[t].next=link[start];    

a[t].v=vv;

link[start]=t;

}

图的遍历:

1、深搜(dfs):

void dfs(int k)

{

f[k]=true;

for(int i=1;i<=n;i++)

if(!f[i]&&a[k][i])dfs(i);

}

*主程序:

memset(f,0,sizeof(f));

for (int i=1;i<=n;i++)

          if (!f[i])  dfs(i);


2、广搜:

Void  bfs(int i);

{

   memset(q,0,sizeof(q));

   int head=0,tail=1;

   q[1]=i;  f[i]=true;

   while (head<tail)

   {

         k=q[++head];  cout>>k;

         for (int j=1;j<=n,j++)

            if (a[k][j] && !f[j])

            {

                 q[++tail]=j;

                 f[j]=true;

             }

   } 

}

要用到队列,暂时不会

***邻接表(dfs):

voiddfs(int k)
{
  for (int i=linkk[k];i;i=e[i].next)//在邻接表中会经常用到
  if(!vis[e[i].y])
  {
  vis[e[i].y]=1;
  dfs(e[i].y);
  }
}

求最短路径:

1、floyed:

求每队顶点之间的最短路径(点)

for (int k=1;k<=n;k++)

      for (int i=1;i<=n;i++)

          for (int j=1;j<=n;j++)

            if  (d[i][k]+d[k][j]<d[i][j] )

  d[i][j]=d[i][k]+d[k][j]


注:k循环一定要放到最外层;

2、dijkstra:

计算一个顶点到所有顶点的最短路径(边)

先找和已求点距离最近的;把这个点加到已知中;重复;

void dijkstra(int st);

{

   for (int i=1;i<=n;i++) dis[i]=a[st][i];

   memset(f,false,sizeof(f));

   f[st]=true;  dis[st]=0;

   for (int i=1;i<n;i++)

   {

        int min=1000000000, k=0;

        for (int j=1;j<=n;j++)

            if (!f[j] &&(dis[j]<min))  min=dis[j],k=j;

        if (k==0)  return; //已经找不到了。

        f[k]=true;  //把k加入集合1;

        for (int j=1;j<=n;j++)  //三角形迭代,更新最短距离

            if (!f[j] &&(dis[k]+a[k][j]<dis[j]))   dis[j]=dis[k]+a[k][j];     

   }

}

注:floyed可以有负权,无负权回路;    dijkstra不能有负权。

3、bellman-ford:

先初始化所有边的最短距离为∞;

取所有边,看能否是距离变短;

如果没有任何松弛,则结束;

如果松弛了n次,则有负权(可以用来判断负权)。


最小生成树:

1、Prim:

在交叉边里取最小权;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值