• ZOJ-2365 Strong Defence 无公共边割边集


    题意:该题的题意晦涩,勉勉强强听别人说了一遍后再读了一遍题才算懂了题意,题图说的是A国因为B国药进攻自己的国家,于是想办法在联通A-B之间的路径上进行阻击。阻击的舰船停留在一个路径上,舰船上都要放置水晶,相同水晶的舰船可能会被一次性摧毁,于是现在要求给出尽可能多的方案来部署舰船,使得同一水晶的舰船能够阻断所有从B到A的路径,每条路径上只能够部署一部舰船。

    分析:题意抽象之后就是一个网络求出从源点到汇点的尽可能多的割边集,且每个割边集没有公共边。根据题目的要求,我们设想从A到B的最短路长度为K,那么假设方案数大于K,那么每个割边集至少要包含该最短路上的一条边,否则存在从A到B的通路,那么这个包含的最优方法是一次包含一条,即便如此该过程也只能够进行K次,超过K次后必定不能够再包含最短路上的任何一条边,因此最后的答案就是K了,然后输出求出最短路之后的距离为1的边集即可。

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    
    const int N = 405;
    int n, m, s, t;
    int dis[N];
    char vis[N], mp[N][N];
    queue<int>q;
    vector<int>v[N];
    
    struct Edge {
        int a, b;
    }e[N*N];
    
    void spfa() {
        memset(dis, 0x3f, sizeof (dis));
        memset(vis, 0, sizeof (vis));
        dis[s] = 0, vis[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int v = 1; v <= n; ++v) {
                if (!mp[u][v]) continue;
                if (dis[v] > dis[u] + 1) {
                    dis[v] = dis[u] + 1;
                    if (!vis[v]) {
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            memset(mp, 0, sizeof (mp));
            scanf("%d %d %d %d", &n, &m, &s, &t);
            int a, b;
            for (int i = 0; i < n; ++i) v[i].clear();
            for (int i = 1; i <= m; ++i) {
                scanf("%d %d", &a, &b);
                mp[a][b] = mp[b][a] = 1;
                e[i].a = a, e[i].b = b;
            }
            spfa();
            printf("%d
    ", dis[t]);
            for (int i = 1; i <= m; ++i) {
                int a = e[i].a, b = e[i].b;
                if (dis[a]+1==dis[b]) {
                    v[dis[a]].push_back(i);
                } else if (dis[b]+1==dis[a]) {
                    v[dis[b]].push_back(i);
                }
            }
            for (int i = 0; i < dis[t]; ++i) {
                printf("%d", v[i].size());
                for (int j = 0; j < v[i].size(); ++j) {
                    printf(" %d", v[i][j]);
                }
                puts("");
            }
        }
        return 0;
    }
  • 相关阅读:
    继承---原型式继承
    CSS中可继承的属性
    函数定义相关
    现代密码学(对称密码——第一部分)
    数据结构练习题(1)
    数据结构与算法(线性表)
    数据结构与算法(绪论)
    大英四期中单词复习
    计算机组成原理_verilog学习_实验二答案(原创)
    现代密码学——第2章古典密码学
  • 原文地址:https://www.cnblogs.com/Lyush/p/3204755.html
Copyright © 2020-2023  润新知