【算法笔记】图论/dp-动态规划 大总结

前言

写于一只蹲在角落的蒟蒻-Z__X…
2020.2.7,图论和 d p dp dp 终于告一段落。蓦然回首,好似已走过许多…不曾细细品味,太多太多又绵延不断地向我涌来…
谨以此纪念 逝去 的图论和 d p dp dp;

图论

  • 图的存储
    首先,图论的基础:存储。这里介绍几种存储结构;
    邻接矩阵
    一种最简单,暴力的存储结构,二维数组存储;
    注:这是读入方式的一种,具体看题目。
     	cin >> n >> m;
    	for (int i=1;i=m;i++)
    	{
         
    		cin >> i >> j >> x;   
    		a[i][j]=a[j][i]=x;
     	}
    
    邻接表(链式前向星)
    邻接表,又叫链式前向星,其实就是链表的思路;
    先开一个 l i n k k linkk linkk 数组, l i n k k [ i ] linkk[i] linkk[i] 表示的是以 i i i 为起点第一条边的编号, e e e 数组存边, e [ i ] . y e[i].y e[i].y 表示终点, e [ i ] . v e[i].v e[i].v 表示权值, e [ i ] . n e x t e[i].next e[i].next 表示下条边的编号;
    邻接表核心就是一个插入函数:
    void insert(int x,int y,int v)  //x为起点,y为终点,v为权值。
    {
           
      e[++t].y=y; e[t].v=v;
      e[t].next=linkk[x]; linkk[x]=t;
    }
    
    还有一个循环同样重要,类似于查询:
    for (int i=linkk[x];i;i=e[i].next)
    
    边表(边集数组)
    一种简便的存储结构,思路同样很简单,就是把所有的边存储到 e e e 数组中,要存储起点,终点,权值。
    struct  node
    {
         
    	int x,y;  //起点和终点
    	int v;    //权值
    }e[maxm];
    
  • 图的遍历
    dfs遍历
    邻接矩阵 d f s dfs dfs 遍历:
    void dfs(int k);
    {
         
    	printf("%d",k);
    	f[k]=true;
    	for (int i=1;i<=n;i++)
         if (!f[i] && a[k][i])  dfs(i);
    }
    
    邻接表 d f s dfs dfs 遍历:
    void dfs(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);
       }
    }
    
    bfs遍历
    邻接矩阵 b f s bfs bfs 遍历:
    void  bfs(int i);
    {
         
    	memset(q,0,sizeof(q));
    	int head=1,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;
             }
            head++;
      	 }	
    }
    
  • 最短路
    Floyd
    k k k 为中转点,更新 i i i j j j 的最短路
    for (int k=1;k<=n;k++)
      for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
          if  (dis[i][k]+dis[k][j]<dis[i][j])
    	    dis[i][j]=dis[i][k]+dis[k][j];
    
    无向图优化版
    void Floyd()
    {
         
    	for (int k
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值