• ACM 实验室2020.10.03天梯赛练习*1


    7-13 垃圾箱分布

    题意:n个点,m个能当作起始点,k条边,起始点不能与n个点距离超过ds,求到n个点的最短距离最长的起始点

    思路:跑m遍dijkstra即可,练习的时候时间不够没写完

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const int maxn = 1000 + 15;
    const double eps = 1e-9;
    
    int n, m, k, ds;
    vector<PII> v[maxn];
    int dis[maxn];
    bool vis[maxn];
    priority_queue<PII, vector<PII>, greater<> > que;
    
    int dijkstra(int x) {
        memset(vis, false, sizeof(vis));
        memset(dis, 0x3f, sizeof dis);
        dis[x] = 0;
        que.push(PII(0, x));
        while (!que.empty()) {
            int point = que.top().second;
            que.pop();
            if (vis[point])
                continue;
            vis[point] = true;
            for (auto i:v[point]) {
                if (dis[i.first] > dis[point] + i.second) {
                    dis[i.first] = dis[point] + i.second;
                    que.push(PII(dis[i.first], i.first));
                }
            }
        }
        int minn = 0x3f3f3f3f;
        for (int i = 1; i <= n; i++) {
            if (dis[i] > ds)
                return 0x3f3f3f3f;
            minn = min(minn, dis[i]);
        }
        return minn;
    }
    
    int main() {
        cin >> n >> m >> k >> ds;
        getchar();
        for (int i = 0; i < k; i++) {
            char s;
            int a = 0, b = 0, c;
            scanf("%c", &s);
            if (s == 'G') {
                cin >> a;
                a += 1000;
                getchar();
            } else {
                while (s != ' ') {
                    a *= 10;
                    a += s - '0';
                    scanf("%c", &s);
                }
            }
            scanf("%c", &s);
            if (s == 'G') {
                cin >> b;
                b += 1000;
                getchar();
            } else {
                while (s != ' ') {
                    b *= 10;
                    b += s - '0';
                    scanf("%c", &s);
                }
            }
            cin >> c;
            getchar();
            v[a].push_back(PII(b, c));
            v[b].push_back(PII(a, c));
        }
        int point = 0;
        int ansmin = -1;
        int ansavg = 0x3f3f3f3f;
        for (int i = 1001; i <= 1000 + m; i++) {
            double minn = dijkstra(i);
            if (minn == 0x3f3f3f3f)
                continue;
            if (ansmin < minn) {
                ansmin = minn;
                int avg = 0;
                for (int j = 1; j <= n; j++)
                    avg += dis[j];
                ansavg = avg;
                point = i;
            } else if (minn == ansmin) {
                int avg = 0;
                for (int j = 1; j <= n; j++)
                    avg += dis[j];
                if (ansavg > avg) {
                    ansavg = avg;
                    point = i;
                }
            }
        }
    
        if (point != 0) {
            cout << "G" << point - 1000 << endl;
            printf("%.1lf %.1lf
    ", ansmin * 1.0, ansavg / (double) n);
        } else
            cout << "No Solution" << endl;
        return 0;
    }
    

      

    7-15 地铁一日游

    题意:n个点m段线路k为为计费距离限制,给m段线路后,q次询问,每次从x站出发,求能拍照的站点

    思路:题目吧啦了一堆,无非是要说以下条件:

        选某个车费中最远的(比如说,我花5块钱能到3个地方,那么选最远的)

                                    路线的端点(注意!这里是指连通路线的端点)

        用Floyed求最短路,每个站点都找到能拍照的站点,对每次查询都dfs一遍。

        靠蒙和猜题意,慢慢写

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const int maxn = 200 + 5;
    const double eps = 1e-9;
    
    struct point {
        int vis = 0;
        int ends = 0;
        vector<int> res;
    } points[maxn];
    int n, m, k;
    int mp[maxn][maxn];
    
    void floyed() {
        for (int K = 1; K <= n; K++)
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                    if (i != j && mp[i][j] > mp[i][K] + mp[K][j])
                        mp[i][j] = mp[i][K] + mp[K][j];
    }
    
    void dfs(int x, int vis) {
        for (int i = 0; i < points[x].res.size(); i++) {
            int tmp = points[x].res[i];
            if (points[tmp].vis != vis) {
                points[tmp].vis = vis;
                dfs(tmp, vis);
            }
        }
    }
    
    int main() {
        memset(mp, 0x3f, sizeof mp);
        cin >> n >> m >> k;
        for (int i = 0; i < m; i++) {
            int u, v, w;
            cin >> u;
            points[u].ends = 1;
            do {
                cin >> w >> v;
                if (w < mp[u][v]) {
                    mp[u][v] = w;
                    mp[v][u] = w;
                }
                u = v;
            } while (getchar() != '
    ');
            points[u].ends = 1;
        }
        floyed();
        for (int i = 1; i <= n; i++) {
            map<int, int> mp1;
            for (int j = 1; j <= n; j++)
                if (mp[i][j] != 0x3f3f3f3f && mp[i][j] > mp1[mp[i][j] / k + 2])
                    mp1[mp[i][j] / k + 2] = mp[i][j];
            for (int j = 1; j <= n; j++)
                if (mp[i][j] == mp1[mp[i][j] / k + 2] || (i != j && mp[i][j] != 0x3f3f3f3f && points[j].ends == 1))
                    points[i].res.push_back(j);
        }
        int q;
        cin >> q;
        for (int i = 1; i <= q; i++) {
            int start;
            cin >> start;
            points[start].vis = i;
            dfs(start, i);
            int first = true;
            for (int j = 1; j <= n; j++)
                if (points[j].vis == i) {
                    if (!first)
                        cout << " ";
                    first = false;
                    cout << j;
                }
            cout << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    在关闭窗体时弹出对话框
    使应用程序在进程中消失
    禁用窗口上的关闭按钮
    洛谷P1080 国王游戏
    洛谷P1443 马的遍历
    算法竞赛入门经典第二版 随笔1
    AcWing 794. 高精度除法
    AcWing 793. 高精度乘法
    AcWing 792. 高精度减法
    AcWing 791. 高精度加法
  • 原文地址:https://www.cnblogs.com/Whiteying/p/13766529.html
Copyright © 2020-2023  润新知