【模板】图论算法模板(持更)

标签: c++ Graph
15人阅读 评论(0) 收藏 举报

图论

图论是个大板块,建模在图论中占有很重要的地位,至于算法就是理解之后代码多敲敲,具体的架构还是差不多的。
图论大概有3个级别,第一级别就是没有边权的图,用于遍历或者强连通SCC跑一波等等;第二级别就是有边权的,这下算法多了,各种最短路和最小生成树都有了,一二级别有时候可以合并,遍历时没有边权实际上边权就是1;然后第三级别就是有流量(dalao们的网络流),当然还有各种变种,比如说加个费用啊什么的。

第一级别

慢慢来,持更嘛

第二级别

由于分块比较多,我直接按算法全部给出了。

SPFA

struct Graph {
    struct edgetype {
        int to, next, dist;
    };
    int n, m;
    std::vector< int > head, dist;
    std::vector< edgetype > edge;
    std::vector< bool > inQ;
    std::queue< int > Q;
    Graph() {
        n = m = 0;
        head.clear(); dist.clear(); edge.clear(); inQ.clear();
    }
    Graph(int n, int m) {
        this->n = n; this->m = m;
        head.resize(n + 1); dist.resize(n + 1); inQ.resize(n + 1);
        head.assign(n + 1, -1);
    }
    void AddEdge(int from, int to, int dist) {
        edge.push_back((edgetype){to, head[from], dist});
        head[from] = edge.size() - 1;
    }
    void SSSP(int s) {
        dist.assign(n + 1, 0x3f3f3f3f);
        inQ.assign(n + 1, false);
        while (!Q.empty()) Q.pop();
        Q.push(s); dist[s] = 0; inQ[s] = true;
        while (!Q.empty()) {
            int u = Q.front(); Q.pop(); inQ[u] = false;
            for (int i = head[u]; i != -1; i = edge[i].next) {
                int v = edge[i].to;
                if (dist[v] > dist[u] + edge[i].dist) {
                    dist[v] = dist[u] + edge[i].dist;
                    if (!inQ[v]) {
                        Q.push(v);
                        inQ[v] = true;
                    }
                }
            }
        }
    }
    int Distance(int s, int t) {
        SSSP(s);
        return dist[t];
    }
};

Dijkstra

struct Graph {
    struct EdgeType {
        int to, next, dist;
    };
    struct HeapNode {
        int point, dist;
        bool operator < (const HeapNode& rhs) const {
            return dist > rhs.dist;
        }
    };
    int n, m;
    std::vector< int > head, dist;
    std::vector< bool > done;
    std::vector< EdgeType > edge;
    std::priority_queue< HeapNode > Q; 
    Graph() {
        n = m = 0;
        edge.clear(); head.clear(); dist.clear(); done.clear();
    }
    Graph(int n, int m) {
        this->n = n; this->m = m;
        head.resize(n + 1); dist.resize(n + 1); done.resize(n + 1);
        head.assign(n + 1, -1);
    }
    void AddEdge(int from, int to, int dist) {
        edge.push_back((EdgeType){to, head[from], dist});       
        head[from] = edge.size() - 1;
    }
    void SSSP(int s) {
        dist.assign(n + 1, 0x3f3f3f3f);
        done.assign(n + 1, false);
        while (!Q.empty()) Q.pop();
        Q.push((HeapNode){s, 0}); dist[s] = 0;
        while (!Q.empty()) {
            int u = Q.top().point; 
            Q.pop();
            if (done[u]) continue;
            done[u] = true;
            for (int i = head[u]; i != -1; i = edge[i].next) {
                int v = edge[i].to;
                if (dist[v] > dist[u] + edge[i].dist) {
                    dist[v] = dist[u] + edge[i].dist;
                    Q.push((HeapNode){v, dist[v]});
                }
            }
        }
    }
    int Distance(int s, int t) {
        SSSP(s);
        return dist[t];
    }
};

Kruskal

struct Graph { 
    struct edgetype { 
        int from, to, dist; 
        bool operator < (const edgetype& rhs) const {
            return dist < rhs.dist;
        }
    };  
    int n, m;
    std::vector< edgetype > edge; 
    std::vector< int > f;
    Graph() {  
        n = m = 0;
        edge.clear(); f.clear();
    }  
    Graph(int n, int m) {
        this->n = n; this->m = m;
        f.resize(n + 1);
    }
    void AddEdge(int from, int to, int dist) {  
        edge.push_back((edgetype){from, to, dist});  
    }  
    inline int FindRoot(int x) {
        return f[x] == x ? x : f[x] = FindRoot(f[x]);
    }
    int MST() {
        int num = 0, ans = 0;
        for (int i = 1; i <= n; i++) f[i] = i;
        sort(edge.begin(), edge.end());
        for (unsigned int i = 0; i < edge.size(); i++) {
            int fu = FindRoot(edge[i].from);
            int fv = FindRoot(edge[i].to);
            if (fu != fv) {
                f[fu] = fv;
                ans += edge[i].dist;
                if (++num == n - 1) break;
            }
        }
        return ans;
    }
};  

Prim

struct Graph {
    struct edgetype {
        int to, next, dist;
    };
    struct heapnode {
        int point, dist;
        bool operator < (const heapnode& rhs) const {
            return dist > rhs.dist;
        }
    };
    int n, m;
    std::vector< int > head, dist;
    std::vector< edgetype > edge;
    std::priority_queue< heapnode > Q; 
    Graph() {
        n = m = 0;
        edge.clear(); head.clear(); dist.clear();
    }
    Graph(int n, int m) {
        this->n = n; this->m = m;
        head.resize(n + 1); dist.resize(n + 1);
        head.assign(n + 1, -1);
    }
    inline void AddEdge(int from, int to, int dist) {
        edge.push_back((edgetype){to, head[from], dist});       
        head[from] = edge.size() - 1;
    }
    int MST() {
        int ans = 0;
        dist.assign(n + 1, 0x3f3f3f3f);
        while (!Q.empty()) Q.pop();
        Q.push((heapnode){1, 0});
        dist[1] = 0;
        while (!Q.empty()) {
            int u = Q.top().point;
            Q.pop();
            ans += dist[u];
            dist[u] = 0;
            for (int i = head[u]; i != -1; i = edge[i].next) {
                int v = edge[i].to;
                if (dist[v] > edge[i].dist) {
                    dist[v] = edge[i].dist;
                    Q.push((heapnode){v, dist[v]});
                }
            }
        }
        return ans;
    }
};

Negative_Cycle

struct Graph {
    struct edgetype {
        int to, next, dist;
    };
    int n, m;
    std::vector< int > head, dist;
    std::vector< edgetype > edge;
    std::vector< bool > visit;
    Graph() {
        n = m = 0;
        head.clear(); dist.clear(); edge.clear(); visit.clear();
    }
    Graph(int n, int m) {
        this->n = n; this->m = m;
        head.resize(n + 1); dist.resize(n + 1); visit.resize(n + 1);
        head.assign(n + 1, -1);
    }
    void AddEdge(int from, int to, int dist) {
        edge.push_back((edgetype){to, head[from], dist});
        head[from] = edge.size() - 1;
    }
    void Negative_Cycle_Search(bool& exist, int u) {
        if (exist) return;
        visit[u] = true;
        for (int i = head[u]; i != -1; i = edge[i].next) {
            int v = edge[i].to;
            if (dist[v] > dist[u] + edge[i].dist) {
                dist[v] = dist[u] + edge[i].dist;
                if (visit[v]) {
                    exist = true;
                    return;
                }
                Negative_Cycle_Search(exist, v);
            }
        }
        visit[u] = false;
    }
    bool Negative_Cycle() {
        dist.assign(n + 1, 0);
        visit.assign(n + 1, false);
        bool exist = false;
        for (int i = 1; i <= n && !exist; i++) 
            Negative_Cycle_Search(exist, i);
        return exist;
    }
};

第三级别

这也要慢慢来,,,总结总是需要时间的

查看评论

图论常用模板

该模板基于刘汝佳算法竞赛入门经典--训练指南 该模板部分参考自《ACM国际大学生程序设计竞赛--算法与实现》 图论常用模板 转载请注明:转自http://blog.csdn.net/...
  • a15129395718
  • a15129395718
  • 2016-09-07 20:13:05
  • 805

KM算法详解+模板

晕了, 我2014年时打过hdu2255(KM算法), 竟然没想起来。。。 原作在这, 代码我的和原作的各贴一份好了 KM算法用来求二分图最大权完美匹配。 本文配合该博文服用更佳:趣写算法系...
  • u014097230
  • u014097230
  • 2016-06-01 12:06:27
  • 608

【数模集】 图论常用算法 基础

图与网络优化概述          图论中所谓的“图”是指某类具体事物和这些事物之间的联系。如果我们用点表示这些具体事物,用连接两点的线段(直的或曲的)表示两个事物的特定的联系,就得到了描述这个“图”...
  • wyh7280
  • wyh7280
  • 2015-08-10 01:12:26
  • 1237

ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)

萌新常用的都在这了,本萌新的模板集。
  • qq_32265245
  • qq_32265245
  • 2016-11-05 18:00:22
  • 11547

最短路(floyd算法)模板

#include #include #define inf 1000000; using namespace std; int map[1000][1000],dis[1000][1000]; int...
  • u013665921
  • u013665921
  • 2014-04-28 13:11:11
  • 838

最小生成树之算法记录【prime算法+Kruskal算法】【模板】

首先说一下什么是树:     1、只含一个根节点     2、任意两个节点之间只能有一条或者没有线相连     3、任意两个节点之间都可以通过别的节点间接相连     4、除了根节点没一个节点...
  • TH226
  • TH226
  • 2015-08-07 16:13:24
  • 983

KM算法 模板

2017年4月3日 | ljfcnyali KM算法大意 1.运用贪心算法初始化标杆。 2.运用匈牙利算法找到完备匹配。 3.如果找不到,则通过修改标杆,增加一些边。 4.重复2,3的步...
  • zz3111057382
  • zz3111057382
  • 2017-05-31 21:39:15
  • 166

Ford-Fulkerson算法模板(最大流)

int dfs(int u,int t,int f) { if(u==t) return f; used[u]=1; for(int i=0;i0) { int d=dfs(...
  • z956281507
  • z956281507
  • 2017-04-23 10:21:15
  • 775

对 模拟退火算法的理解 初步应用 以及 模板

一开始接触到 模拟退火算法,根本不知其为何物。然后根据一道我胡乱做错的题目(RQNOJ No.31),竟然牵扯到了这个算法,最后竟然高速AC了,所以看来这个算法还是很厉害的。 首先,模拟退火算法 顾...
  • JerryDung
  • JerryDung
  • 2012-09-02 08:51:23
  • 793

最小生成树-Kruskal算法(模板)

Kruskal基本算法:每次选取最短的边,看该边相连的两点是否在同一集合内,若在,则跳过,若不在,就把两个点合并,判断与合并都用并查集实现。 Kruskal的复杂度是O(ElogE),适合稀疏图。...
  • algzjh
  • algzjh
  • 2016-08-25 10:49:07
  • 1365
    个人资料
    持之以恒
    等级:
    访问量: 361
    积分: 260
    排名: 29万+
    文章分类
    文章存档