算法复习:图

一、拓扑排序

leetcode 207. 课程表

维护一个数据结构用于存储图的入度或者出度的结构,每次删除入度=0的点及它的出度连线,直到不存在入度=0或者所有节点都已经删除为止。
具体实现时需要有一个标记数组标记已经删除的结点,存储每一个点的入度是多少,出度所连的点有哪些
struct discribe
{
    int num;
    queue<int>node;
};
class Solution {
public:

    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        int lable[numCourses];
        memset(lable,0,sizeof(lable));
        map<int,struct discribe>inner;
        for(int i=0;i<numCourses;i++)//舒适化
        {
            inner[i].num=0;
            queue<int> tmp;
            inner[i].node=tmp;
        }
        for(int i=0;i<prerequisites.size();i++)
        {
            queue<int> tmp;
            tmp=inner[prerequisites[i][1]].node;//1是前点 0是后点
            tmp.push(prerequisites[i][0]);
            inner[prerequisites[i][0]].num++;//给后点的入度+1
            inner[prerequisites[i][1]].node=tmp;//接在后面的点集合
        }
        while(true)
        {
            int loop_or_not=0;
            for(int i=0;i<numCourses;i++)
            {
                if(lable[i]==1||inner[i].num!=0)
                    continue;
                queue<int> tmp=inner[i].node;
                while(tmp.size())
                {
                    inner[tmp.front()].num--;
                    tmp.pop();
                }
                lable[i]=1;
                loop_or_not=1;
                break;
            }
            if(loop_or_not==0)//扫面一遍以后不在有更新
                break;
        }
        for(int i=0;i<numCourses;i++)
        {
            if(lable[i]==0)
                return false;
        }
        return true;
    }
};
leetcode 207

二、并查集

leetcode 684. 冗余连接

map存当前节点的直接father是谁,通过循环查找每一个节点的祖先,如果是冗余边,该边所连的两个点有共同祖先
无向图的father更新策略1:首先每个点的father初始化为自己,设置标记数组记录当前点是否被其他点当作father,被当作过father的优先做别人的儿子,如果两个都做过father,就把这两个点的祖先连在一起
无向图的father更新策略2:寻找这两个点的祖先,把这两个点的祖先连在一起即可
路径压缩:每通过循环查询一次祖先,就把祖先当作查询点的father
class Solution {
public:
    map<int,int>donser;
    int find_source(int x)//寻找祖先
    {
        int tmp=x;
        while(donser[x]!=x)
            x=donser[x];
        donser[tmp]=x;//路径压缩
        return x;
    }
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        int lable[1001];
        for(int i=0;i<=edges.size();i++)
        {
            donser[i]=i;
            lable[i]=0;
        }
        for(int i=0;i<edges.size();i++)
        {
            int x=find_source(edges[i][0]);
            int y=find_source(edges[i][1]);
            if(x==y)
                return edges[i];
            /*if(edges[i][0]==x&&lable[edges[i][1]]==0)
            {
                donser[edges[i][0]]=edges[i][1];
                lable[edges[i][1]]=1;
            }
            else if(edges[i][1]==y&&lable[edges[i][0]]==0)
            {
                donser[edges[i][1]]=edges[i][0];
                lable[edges[i][0]]=1;
            }
            else*/
                donser[x]=y;
        }
        return edges[edges.size()-1];
    }
};
leetcode 684
原文地址:https://www.cnblogs.com/dzzy/p/12369132.html