算法竞赛知识提要4

来源:互联网 发布:淘宝供销平台官网进入 编辑:程序博客网 时间:2024/06/05 18:02

再来说说图(young)

  • 有向图术语
    这里写图片描述

这里写图片描述

特别的,把有向无环图称为DAG.对于每个顶点我们给他一个编号,第i号顶点vi,如果vi到vj有边有i《j成立,这样的编号方式称为拓排序。如上图的拓排序,编号方式从左到右,则边的指向也从左到右,这样就可以用dp的方式求解。

  • 图表示

    1.邻接矩阵
    邻接矩阵使用|V|*|V|的二维矩阵来表示图的,g[i][j]表示顶点i和j的状态。好处就是可以用常数的时间迅速得到两个顶点是否有边的存在,但是需要花费|V2|的内存空间,在边很少的稀疏图中这会造成巨大的浪费。此外,重边和自环也要考虑哦。

    这里写图片描述

    这里写图片描述

    这里写图片描述

2.邻接表
只需要把顶点做成链表头结点,谁和他相连就把他加入链表中。这样只需要|V|+|E|的内存空间。但是邻接表实现会比较复杂,查询两个顶点是否有边,这需要遍历一遍链表才知道。

这里写图片描述

例题

  1. 二分图判定
    这里写图片描述
//输入,注意是无向图两边都得连一次//G[i]里的值就是i和它是否相连vector<int>G[max_v];//color[G[i][j]]表示与i相连的j,j的颜色,只有-1,1int color[max_v];int v;bool dfs(int v,int c){     //将v进行染色     color[v] = c;      //遍历与他相连的顶点,两种情况需要讨论没染色或同色,不同色继续往前走就好了     for(int i=0;i<G[v].size();i++){         if(color[G[v][i]]==c) return false;         if(color[G[v][i]]==0 && !dfs(G[v][i],-c))         return false;     }     return true;}void solve(){     for(int i=0;i<v;i++){        if(color[i]==0){           if(!dfs(i,1)){              cout<<"No!"<<endl;              return;           }        }     }      cout<<"YES!"<<endl;      return;}  }

2.最短路径问题

贴一个大神的帖子