• 图论 List


    题目


        #A 小 K 的农场 (Unaccepted)
        #B 信息传递 (Unaccepted)
        #C 最短路计数 (Accepted)
        #D 通往奥格瑞玛的道路 (Accepted)

       #E 公路修建 (Unaccepted)

       #F 货车运输 (Unaccepted)

       #G 图的m着色问题  (Unaccepted)


    1. DFS & BFS

    // 八皇后
    // Au: GG
    
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int v[15], n, ans = 0;
    bool f[15];
    
    void dfs(int i) {
        if (i > n) {
            ans++;
            if (ans <= 3) {
                for (int j = 1; j <= n; j++) {
                    printf("%d ", v[j]);
                }
                printf("
    ");
            }
            return;
        }
        for (int k = 1; k <= n; k++) {
            if (f[k]) continue;
            bool pd = true;
            for (int j = 1; j < i; j++)
                if (v[j] == k || abs(i - j) == abs(v[j] - k)) pd = false;
            if (pd) {
                v[i] = k;
                f[k] = true;
                dfs(i + 1);
                f[k] = false;
                v[i] = 0;
            }
        }
    }
    
    int main() {
        scanf("%d", &n);
        dfs(1);
        printf("%d", ans);
        return 0;
    }
    
    // 马的遍历
    // Au: GG
    
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    
    int n, m;
    int dx[8] = { -2, -1, 1, 2, 2, 1, -1, -2};
    int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
    int map[400 + 3][400 + 3];
    struct bbc {
        int x, y, n;
    } s;
    queue<bbc> q;
    
    int main() {
        memset(map, -1, sizeof(map));
        scanf("%d%d%d%d", &n, &m, &s.x, &s.y);
        map[s.x][s.y] = 0;
        q.push(s);
    
        while (!q.empty()) {
            bbc a;
            for (int i = 0; i < 8; i++) {
                a = q.front();
                int bx = a.x + dx[i];
                int by = a.y + dy[i];
                if (bx < 1 || bx > n || by < 1 || by > m || map[bx][by] != -1)
                    continue;
                a.x = bx;
                a.y = by;
                a.n++;
                q.push(a);
                map[bx][by] = a.n;
            }
            q.pop();
        }
    
        for (int k = 1; k <= n; k++) {
            for (int r = 1; r <= m; r++)
                printf("%-5d", map[k][r]);
            printf("
    ");
        }
        return 0;
    }
    
    /* Luogu P1126 机器人搬重物
     * Au: GG
     */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 53;
    int n, m, g[N][N], endx, endy;
    bool d[N][N][4];
    
    struct status {
        int x, y, t;
        char d;
    } sta;
    queue<status> q;
    
    char ltd(char dir) {
        if (dir == 'N') return 'W';
        else if (dir == 'W') return 'S';
        else if (dir == 'S') return 'E';
        else return dir = 'N';
    }
    
    char rtd(char dir) {
        if (dir == 'N') return 'E';
        else if (dir == 'E') return 'S';
        else if (dir == 'S') return 'W';
        else return 'N';
    }
    
    int did(char dir) {
        if (dir == 'N') return 0;
        else if (dir == 'E') return 1;
        else if (dir == 'S') return 2;
        else return 3;
    }
    
    int main() {
        int h;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) {
                scanf("%d", &h);
                if (h) {
                    g[i][j] = -1;
                    g[i + 1][j] = -1;
                    g[i][j + 1] = -1;
                    g[i + 1][j + 1] = -1;
                }
            }
    
        scanf("%d%d%d%d %c", &sta.x, &sta.y, &endx, &endy, &sta.d);
        sta.x++; sta.y++; endx++; endy++;
        sta.t = 0; d[sta.x][sta.y][did(sta.d)] = true;
    
        q.push(sta);
        while (!q.empty()) {
            status a = q.front(), b;
            q.pop();
    
            if (a.x == endx && a.y == endy) {
                printf("%d
    ", a.t); return 0;
            }
            d[a.x][a.y][did(a.d)] = true;
            // printf("Status a(%d, %d, %c) = %d
    ", a.x, a.y, a.d, a.t);
    
            // Creep & Walk & Run
            for (int step = 1; step <= 3; step++) {
                if (a.d == 'N') {
                    b.x = a.x - step; b.y = a.y; 
                } else if (a.d == 'S') {
                    b.x = a.x + step; b.y = a.y;
                } else if (a.d == 'W') {
                    b.x = a.x; b.y = a.y - step;
                } else {
                    b.x = a.x; b.y = a.y + step;
                }
                b.d = a.d; b.t = a.t + 1;
                if (g[b.x][b.y] == 0 && !d[b.x][b.y][did(b.d)]) {
                    if (b.x > 1 && b.x < n + 1 && b.y > 1 && b.y < m + 1) 
                        q.push(b);
                    else break;
                } else break;
            }
    
            // Left
            b.x = a.x; b.y = a.y; b.t = a.t + 1;
            b.d = ltd(a.d);
            if (!d[b.x][b.y][did(b.d)]) 
                if (b.x > 1 && b.x < n + 1 && b.y > 1 && b.y < m + 1)
                    q.push(b);
    
            // Right
            b.x = a.x; b.y = a.y; b.t = a.t + 1;
            b.d = rtd(a.d);
            if (!d[b.x][b.y][did(b.d)]) 
                if (b.x > 1 && b.x < n + 1 && b.y > 1 && b.y < m + 1) 
                    q.push(b);
        }
    
        printf("-1
    ");
        return 0;
    }
    /*
    9 10
    0 0 0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 0 1 0
    0 0 0 1 0 0 0 0 0 0
    0 0 1 0 0 0 0 0 0 0
    0 0 0 0 0 0 1 0 0 0
    0 0 0 0 0 1 0 0 0 0
    0 0 0 1 1 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    1 0 0 0 0 0 0 0 1 0
    7 2 2 7 S
    */
    
    /*
    问题(估计是致命问题)给你一个图(点阵,不是块阵)
    0 0 0 0 0 0 0
    0 S 1 T 1 0 0
    机器人在S处面向右方,根据你82-97行的前进代码,机器人可以到达T处,但是事实上并不能到达,所以题目数据的图(点阵)如下
     0 0 0 0 0 0-1-1 0 0 0
     0 0 0 0 0 0-1-1-1-1 0
     0 0 V-1-1 V 0 T-1-1 0
     0 0-1-1-1 0 0 0 0 0 0
     0 0-1-1 0 0-1-1 0 0 0
     0 0 V 0 0-1-1-1 0 0 0
     0 0 0-1-1-1-1 0 0 0 0
     0 0 S-1-1-1 0 0 0 0 0
    -1-1 0 0 0 0 0 0-1-1 0
    -1-1 0 0 0 0 0 0-1-1 0
    7步的行径路径给你了
    
    左转(面向右边)
    左转(面向上方)
    walk
    run(这步其实不能走,但是按照你的代码是可以走的)
    右转(面向右边)
    run(这步其实也不能走,但是按照你的代码也是可以走的)
    walk
    
    以上七步S是起点V是途经点T是终点
    
    连这个错误你都犯,你可以去面壁一天了。。。(什么时候可以穿墙了。。。)
    还有,让zzh去面壁半天,连这么简单的错误都看不出来。
    我先走了
    ——8:45 by dph
    */
    
    /* P1118 [USACO06FEB]数字三角形Backward Digit Su…
     * Au: GG
     */
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 15;
    int n, sum, tri[N][N], d[N];
    bool v[N];
    
    void triangle() { // triangle table
        for (int i = 1; i <= n; i++) tri[i][1] = tri[i][i] = 1;
        for (int i = 2; i <= n; i++) 
            for (int j = 2; j < i; j++) 
                tri[i][j] = tri[i - 1][j] + tri[i - 1][j - 1];
    
        // for (int i = 1; i <= n; i++) {
        //     for (int j = 1; j <= i; j++) 
        //         printf("%d ", tri[i][j]);
        //     printf("
    ");
        // }
    }
    
    bool dfs(int f, int s) {
        // printf("dfs(%d, %d, d = %d)
    ", f, s, d[f - 1]);
        if (f > n) {
            if (s == sum) return true;
            else return false;
        }
        for (int i = 1; i <= n; i++)
            if (!v[i] && s + i * tri[n][f] <= sum) {
                v[i] = true; d[f] = i;
                if (dfs(f + 1, s + i * tri[n][f])) return true;
                v[i] = false;
            }
        return false;
    }
    
    int main() {
        scanf("%d%d", &n, &sum);
        triangle();
    
        if (dfs(1, 0)) {
            for (int i = 1; i <= n; i++) printf("%d ", d[i]);
        }
        
        return 0;
    }
    
    /* Luogu P1141 01迷宫
     * Au: GG
     */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 1000 + 5;
    int n, m, g[N][N]; int vis[N][N], vs, vcnt[100000 + 5];
    int dx[] = {0, -1, 1, 0}, dy[] = {-1, 0, 0, 1};
    
    struct point {
        int x, y;
    };
    
    int read() {
        char a = getchar();
        while (a != '0' && a != '1') a = getchar();
        return a - '0';
    }
    
    bool check(point i) {
        if (i.x < 1 || i.x > n) return false;
        if (i.y < 1 || i.y > n) return false;
        return true;
    }
    
    int bfs(int u, int v) {
        if (vis[u][v]) return vcnt[vis[u][v]]; 
    
        int cnt = 0; vs++;
        queue<point> q;
        point a, b; a.x = u, a.y = v;
        q.push(a);
    
        while (!q.empty()) {
            a = q.front();
            q.pop(); if (vis[a.x][a.y]) continue;
            vis[a.x][a.y] = vs; cnt++;
    
            for (int i = 0; i < 4; i++) {
                b.x = a.x + dx[i];
                b.y = a.y + dy[i];
                if (check(b) && (g[b.x][b.y] != g[a.x][a.y]) && !vis[b.x][b.y]) q.push(b);
            }
        }
    
        return vcnt[vs] = cnt;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                g[i][j] = read();
            }
        }
    
        int xx, yy;
        while (m--) {
            scanf("%d%d", &xx, &yy);
            printf("%d
    ", bfs(xx, yy));
        }
        
        return 0;
    }
    

     2. 最小生成树

    // 最小生成树
    // Au: GG
    
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    int n, m, f[5000 + 3], sum;
    struct edge {
        int x, y, w;
        bool operator < (const edge &a) const {
            return w > a.w;
        }
    } temp;
    priority_queue<edge> G;
    
    int find(int x) {
        return (f[x] == x) ? x : f[x] = find(f[x]);
    }
    void join(int x, int y) {
        f[find(y)] = find(x);
    }
    
    int main() {
        int x, y, z, flag = 0;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%d", &x, &y, &z);
            temp.x = x; temp.y = y; temp.w = z; G.push(temp);
        }
        for (int i = 1; i <= n; i++) f[i] = i;
        while (!G.empty()) {
            temp = G.top(); G.pop();
            if (find(temp.x) != find(temp.y)) join(temp.x, temp.y), sum += temp.w, flag++;
        }
        if (flag < n - 1) printf("orz
    ");
        else printf("%d
    ", sum);
        return 0;
    }
    

    3. 并查集

    /* 并查集
     * Au: GG
     */
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int maxn = 10000 + 3;
    int n, m, z, x, y, f[maxn];
    int find(int x) {
        return (f[x] == x) ? x : f[x] = find(f[x]);
    }
    inline void join(int x, int y) {
        f[find(y)] = find(x);
    }
    int main() { 
        scanf("%d%d", &n, &m);
        while (n--) f[n] = n;
        while (m--) {
            scanf("%d%d%d", &z, &x, &y);
            if (z == 1) {
                join(x, y);
            } else {
                if (find(x) == find(y)) printf("Y
    ");
                else printf("N
    ");
            }
        }
        return 0;
    }
    

    Post author 作者: Grey
    Copyright Notice 版权说明: Except where otherwise noted, all content of this blog is licensed under a CC BY-NC-SA 4.0 International license. 除非另有说明,本博客上的所有文章均受 知识共享署名 - 非商业性使用 - 相同方式共享 4.0 国际许可协议 保护。
  • 相关阅读:
    VS2005快捷键(转)
    codeSmish使用《转》
    WinForm TextBox数据绑定
    NetTiers抛出"Unable To Load NetTiersServiceSection“的异常
    DELPHi第三方控件使用方法(摘录)
    遠程連接操作
    不同服务器数据库之间的数据操作
    delphi 关闭 MDI 子窗体
    VSS使用手册(转)
    delphi 快捷键
  • 原文地址:https://www.cnblogs.com/greyqz/p/7211147.html
Copyright © 2020-2023  润新知