離散上機

傳遞閉包

/**
 * 傳遞閉包
 */
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int n, m, a[111][111], flag[111];

void warshell() {
    for (int j = 1; j <= n; j++) {
        for (int i = 1; i <= n; i++) {
            if (a[i][j]) {
                for (int k = 1; k <= n; k++) {
                    a[i][k] = a[i][k] + a[j][k];
                    if (a[i][k] >= 1) a[i][k] = 1;
                }
            }
        }
    }
}
int main() {
    while (cin >> n >> m) {
        int x, y;
        memset(a, 0, sizeof(a));
        memset(flag, 1, sizeof(flag));
        for (int i = 0; i < m; i++) {
            cin >> x >> y;
            a[x][y] = 1;
        }
        warshell();
        int ans = 0;
        for (int j = 1; j <= n; j++) {
            for (int i = 1; i <= n; i++) {
                if (i == j) {
                    if (a[i][j]) {
                        flag[j] = 0;
                        break;
                    }

                } else if (!a[i][j] && !a[j][i]) {
                    flag[j] = 0;
                    break;
                }
            }
            if (flag[j]) ans++;
        }
        cout << ans << endl;
    }
    return 0;
}

 

偏序關係

/**
 * 偏序關係
 * 自反性   反對稱性    傳遞性
 */
#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int n, a[111][111];
int main() {
    int x, y;
    while (cin >> n) {
        int flag = 1;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
            }
        }

        for (int i = 0; i < n; i++) {
            // 判斷是否 滿足  自反性
            if (!a[i][i]) {
                flag = 0;
                break;
            }

            for (int j = 0; j < n; j++) {
                //判斷是否滿足反對稱
                if (a[i][j] && a[j][i] && i != j) {
                    flag = 0;
                    break;
                }
                // 判斷是否滿足傳遞
                if (a[i][j]) {
                    for (int k = 0; k < n; k++) {
                        if (a[j][k] && !a[i][k]) {
                            flag = 0;
                            break;
                        }
                    }
                }
            }
        }
        printf(flag == 1 ? "yes\n" : "no\n");
    }
    return 0;
}

雙射。

#include <c++/4.2.1/bits/stdc++.h>
using namespace std;

int main() {
    int n, m, k, a[11111], b[11111];
    while (cin >> n >> m >> k) {
        memset(a, -1, sizeof(a));
        memset(b, -1, sizeof(b));
        int x, y, num;
        for (int i = 0; i < n; i++) {
            cin >> num;
            a[num] = 0;
        }
        for (int i = 0; i < m; i++) {
            cin >> num;
            b[num] = 0;
        }
        while (k--) {
            cin >> x >> y;
            a[x]++;
            b[y]++;
        }

        int flag = 1;
        for (int i = 1; i <= 10000; i++) {
            if (a[i] > 1) {
                flag = 0;
                break;
            }
        }
        for (int i = 1; i <= 10000; i++) {
            if (b[i] < 1 && b[i] != -1) {
                flag = 0;
                break;
            }
        }
        if (flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

羣的判定

#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
int arr[110];  // 存放羣中的數據
int num[110];  // 存放逆元
int b[110];    // 存放要查詢的數據
int main() {
    int n, m, q;
    while (cin >> n >> m >> q) {
        int flag = 0;
        memset(num, -1, sizeof(num));

        for (int i = 1; i <= n; i++) {
            cin >> arr[i];
            if (arr[i] == 0) flag = 1;  // 要想G是羣   0必須存在
        }
        for (int i = 1; i <= q; i++) {
            cin >> b[i];
        }

        num[0] = 0;  // 0的逆元是0
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                // 在羣中找每個元素的逆元  即 元素i 和 元素j 都在羣中 且
                // i+j%m==0
                if (flag && (arr[i] + arr[j]) % m == 0) {
                    num[arr[i]] = arr[j];
                    num[arr[j]] = arr[i];
                    break;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            if (num[arr[i]] == -1) {  // 要想成羣  每個元素都有逆元
                flag = 0;
            }
        }

        if (!flag) {
            cout << "-1" << endl;
        } else {
            for (int i = 1; i <= q; i++) {
                cout << num[b[i]] << endl;
            }
        }
    }
    return 0;
}

補圖

#include <bits/stdc++.h>
using namespace std;

int main() {
    int a[505][505], n, t;
    while (cin >> n) {
        int deg = 0;
        int ans_max = 0;
        int ans_min = 550;
        for (int i = 1; i <= n; i++) {
            deg = 0;
            for (int j = 1; j <= n; j++) {
                cin >> t;
                a[i][j] = (t == 0) ? 1 : 0;
                a[i][j] = (i == j) ? 0 : a[i][j];
                if (a[i][j] == 1) deg++;
            }

            ans_max = max(ans_max, deg);
            ans_min = min(ans_min, deg);
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++)
                printf(j == n ? "%d\n" : "%d ", a[i][j]);
        }
        cout << ans_max << ' ' << ans_min << endl;
    }

    return 0;
}

指定長度的路徑數

#include <bits/stdc++.h>
using namespace std;
int n;
int a[505][505], b[505][505], c[505][505];
void make() {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            c[i][j] = 0;
            for (int k = 0; k < n; k++) c[i][j] += a[i][k] * b[k][j];
        }
    }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) b[i][j] = c[i][j];
}
int main() {
    int k;
    while (cin >> n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
                b[i][j] = a[i][j];
            }
        }
        cin >> k;
        // k條路經  是  k-1次冪
        while (--k) {
            make();
        }

        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) ans += b[i][j];

        cout << ans << endl;
    }
    return 0;
}

最小生成樹

#include <c++/4.2.1/bits/stdc++.h>
using namespace std;
struct node {
    int parent;
    int u, v, w;
} a[102400];

bool cmp(node a, node b) { return a.w < b.w; }

int find_root(int x) {
    if (x == a[x].parent) {
        return x;
    }
    return find_root(a[x].parent);
}

void union_set(int u, int v) {
    int xr = find_root(u);
    int yr = find_root(v);
    a[xr].parent = a[yr].parent;
}

int main() {
    int n, m;
    while (cin >> n >> m) {
        for (int i = 1; i <= m; i++) {
            cin >> a[i].u >> a[i].v >> a[i].w;
        }

        sort(a + 1, a + m + 1, cmp);
        for (int i = 1; i <= n; i++) {  // 每個點的祖宗都是自己
            a[i].parent = i;
        }
        int ans = 0;  // 記錄最小的權值和
        int cnt = 0;  // 記錄邊的個數
        for (int i = 1; i <= m; i++) {
            if (find_root(a[i].u) != find_root(a[i].v)) {
                cnt++;
                ans += a[i].w;
                union_set(a[i].u, a[i].v);  // 將不形成環的兩邊連起來
            }
        }
        // n個點  n-1條邊  否則不能構成最小生成樹
        if (cnt == n - 1)
            cout << ans << endl;
        else
            cout << "-1" << endl;
    }
}

 

發佈了137 篇原創文章 · 獲贊 27 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章