zoukankan      html  css  js  c++  java
  • 读书笔记

    /**
    给定一个具有n个顶点的图。要给图上每个顶点染色,并且要让相邻的定点颜色不同。
    问能否只用两种颜色完成。
    规模:
    1 <= n <= 1000
    */
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <vector>
    using namespace std;
    const int N = 1000 + 5;
    
    int n, m;
    vector<int> G[N];
    int color[N];
    
    int dfs(int v, int c)
    {
        color[v] = c;
        for(int i = 0; i < G[v].size(); i++)
        {
            if(color[G[v][i]] == c) //颜色相同不能染
                return 0;
            if(color[G[v][i]] == 0 && !dfs(G[v][i], -c)) //当前可以染色,但是以后会失败
                return 0;
        }
        return 1;
    }
    
    void read()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
    }
    
    void solve()
    {
        read();
        for(int i = 0; i < n; i++)
        {
            if(color[i] == 0)
            {
                if(!dfs(i, 1))
                {
                    printf("No
    ");
                    return;
                }
            }
        }
        printf("Yes
    ");
    }
    
    int main()
    {
        solve();
        return 0;
    }
    /**
    哈哈,终于到模板问题了。
    最短路算法的核心之处就是一个状态转移
    d[i] = min(d[i], d[j] + length(j,i))
    Bellman-Ford算法一个以考虑边来优化的算法
    就是不断遍历所有的边,如果可以优化d[],那么就优化。
    直到有一次遍历所有边都没有办法优化了为止
    复杂度O(NE)。
    使用FIFO队列,最坏O(NE)
    */
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <vector>
    #include <queue>
    using namespace std;
    const int N = 20000 + 5;
    const int INF = 0x3f3f3f3f;
    struct Edge
    {
        int u;
        int v;
        int w;
        Edge(){}
        Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w) {}
    };
    
    vector<int> G[N];
    vector<Edge> edge;
    int n, m;
    int inque[N];
    int d[N];
    int cnt[N];
    int pre[N];
    
    void init()
    {
        for(int i = 0; i < N; i++)
            G[i].clear();
        edge.clear();
    }
    
    void read()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < m; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            edge.push_back(Edge(u, v, w));
            G[u].push_back(edge.size() - 1);
        }
    }
    
    bool Bellman_Ford(int s)
    {
        memset(inque, 0, sizeof(inque));
        memset(cnt, 0, sizeof(cnt));
        for(int i = 0; i < n; i++)
            d[i] = INF;
        queue<int>  Q;
        while(Q.size()) Q.pop();
        Q.push(s);
        d[s] = 0;
        inque[s] = 1;
    
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop(); inque[u] = 0;
            for(int i = 0; i < G[u].size(); i++)
            {
                Edge &e = edge[G[u][i]];
                if(d[e.v] > d[e.u] + e.w)
                {
                    d[e.v] = d[e.u] + e.w;
                    pre[e.v] = pre[e.u];
                    if(!inque[e.v])
                    {
                        Q.push(e.v);
                        inque[e.v] = 1;
                        cnt[e.v]++;
                        if(cnt[e.v] > n)
                            return false;
                    }
                }
            }
        }
        return true;
    }
    
    int main()
    {
        init();
        read();
        if(!Bellman_Ford(0))
        {
            printf("Negative Circle
    ");
            return 0;
        }
        for(int i = 0; i < n; i++)
            printf("%d
    ", d[i]);
        return 0;
    }
    /**
    带堆优化的Dijstra算法,复杂度最坏O(n^2),比BELLMAN-FORD稳定
    模板算法
    */
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <vector>
    #include <queue>
    using namespace std;
    typedef pair<int,int> P;
    const int N = 20000 + 5;
    const int INF = 0x3f3f3f3f;
    struct Edge
    {
        int u;
        int v;
        int w;
        Edge(){}
        Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w) {}
    };
    
    vector<int> G[N];
    vector<Edge> edge;
    int n, m;
    int d[N];
    int pre[N];
    
    void init()
    {
        for(int i = 0; i < N; i++)
            G[i].clear();
        edge.clear();
    }
    
    void read()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < m; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            edge.push_back(Edge(u, v, w));
            G[u].push_back(edge.size() - 1);
        }
    }
    
    void Dijkstra(int s)
    {
        for(int i = 0; i < n; i++)
            d[i] = INF;
        d[s] = 0;
        priority_queue<P, vector<P>, greater<P> > pq;
        pq.push(P(d[s], s));
    
        while(!pq.empty())
        {
            P t = pq.top(); pq.pop();
            int u = t.second;
            if(d[u] < t.first) continue;
            for(int i = 0; i < G[u].size(); i++)
            {
                Edge &e = edge[G[u][i]];
                if(d[e.v] > d[e.u] + e.w)
                {
                    d[e.v] = d[e.u] + e.w;
                    pre[e.v] = e.u;
                    pq.push(P(d[e.v], e.v));
                }
            }
        }
    }
    
    int main()
    {
        init();
        read();
        Dijkstra(0);
        for(int i = 1; i < n; i++)
            printf("%d
    ", d[i]);
        return 0;
    }
    /**
    Floyd算法
    5行
    所有的最短路,O(N^3)
    传递闭包
    适应于规模很小的题,但很有用
    **/
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <vector>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int N = 500 + 5;
    int d[N][N];
    int n;
    
    void Floyd()
    {
        memset(d, 0x3f, sizeof(d));
        for(int k = 0; k < n; k++)
        {
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < n; j++)
                {
                    if(d[i][j] <= INF && d[i][j] > d[i][k] + d[k][j])
                    {
                        d[i][j] = d[i][k] + d[k][j];
                    }
                }
            }
        }
    }
    
    int main()
    {
        Floyd();
    
        //To do
    
        return 0;
    }
    如果有错误,请指出,谢谢
  • 相关阅读:
    JavaScript中的Date对象
    补零函数和随机数函数
    设置与获取自定义属性
    eval()
    获取DOM元素样式
    do{}while() 循环
    ++ 运算符
    switch 语句
    git
    webpack
  • 原文地址:https://www.cnblogs.com/Alruddy/p/7197775.html
Copyright © 2011-2022 走看看