弱省互測#0 t3

Case 1 題意

要求給出下面代碼的答案而後構造輸入。
給一個圖, n 個點 m 條邊 q 次詢問,輸出全部點對之間最大權值最小的路徑。c++

題解

把每個詢問的輸出當作一條邊,建一棵最小生成樹。spa

Case 3 題意

給輸出,要求構造輸入使得用所給代碼運行後獲得的輸出和給出的輸出相同。
所給代碼:n 次 Dijkstra 求兩點間最短路code

分析

考慮一下貪心。排序

題解

首先仍是把每一條最短路的詢問結果當作一條邊,而後咱們把這些邊排序。
對於每一條邊,若是這兩個點如今的距離大於這條邊的權值,咱們就把這條邊加進去,更新全部點對
的距離。
正確性顯然。
如今證實這樣作邊數最短:
假設這樣獲得的構造方案爲 A ,假設還有一種構造方案是 B ,而且邊數更少。
那麼在 A 中確定存在一條邊,在 B 中不存在。
因而在 B 中,這一條邊的兩個端點之間的距離,確定大於 A 中這條邊的邊權。
不然若是相等的話,在 A 中就不會選擇這一條邊。
所以, B 這個方案確定是非法的,也就是說, A 是邊數最少的構造方案。three

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

namespace one {
    const int N=1015, M=1000015;
    struct E {
        int x, y, w;
    }e[M];
    int p[N], n, tot, m;
    bool cmp(const E &a, const E &b) {
        return a.w<b.w;
    }
    int find(int x) {
        return x==p[x]?x:p[x]=find(p[x]);
    }
    void work() {
        scanf("%d%d", &n, &m);
        printf("%d %d\n", n, m);
        int cnt=0;
        for(int i=1; i<=n; ++i) {
            for(int j=i+1; j<=n; ++j) {
                e[cnt].x=i;
                e[cnt].y=j;
                scanf("%d", &e[cnt].w);
                ++cnt;
            }
        }
        for(int i=1; i<=n; ++i) {
            p[i]=i;
        }
        sort(e, e+cnt, cmp);
        for(int i=0; i<cnt; ++i) {
            int x=e[i].x, y=e[i].y, fx=find(x), fy=find(y), w=e[i].w;
            if(fx!=fy) {
                p[fx]=fy;
                ++tot;
                printf("%d %d %d\n", x, y, w);
            }
        }
        for(; tot<=m; ++tot) {
            printf("%d %d %d\n", 1, 1, 0);
        }
    }
}
namespace two {
    const int mo1=9999991, mo2=3333331;
    typedef long long ll;
    int ipow(int a, int b, int mo) {
        int x=1;
        for(; b; b>>=1, a=(ll)a*a%mo) if(b&1) x=(ll)x*a%mo;
        return x;
    }
    void work() {
        int n;
        scanf("%d", &n);
        printf("%d\n", n);
        for(int i=1; i<=n; ++i) {
            static char s[100005];
            scanf("%s", s+1);
            int now1=0, now2=0, len=strlen(s+1);
            for(int i=1; i<=len; ++i) {
                now1=(now1*10+s[i]-'0')%mo1;
                now2=(now2*10+s[i]-'0')%mo2;
            }
            for(int x=1; x<=10000; ++x) {
                int h1=ipow(x, x, mo1), h2=ipow(x, x, mo2);
                if(h1==now1 && h2==now2) {
                    printf("%d ", x);
                    break;
                }
            }
        }
    }
}
namespace three {
    int d[1005][1005];
    struct E {
        int x, y, w;
    }e[1000005];
    bool cmp(const E &a, const E &b) {
        return a.w<b.w;
    }
    void work() {
        int n, m, cnt=0, tot=0;
        scanf("%d%d", &n, &m);
        printf("%d %d\n", n, m);
        for(int i=1; i<=n; ++i) {
            for(int j=i+1; j<=n; ++j) {
                e[cnt].x=i;
                e[cnt].y=j;
                scanf("%d", &e[cnt].w);
                cnt++;
            }
        }
        memset(d, 0x3f, sizeof d);
        for(int i=1; i<=n; ++i) {
            d[i][i]=0;
        }
        sort(e, e+cnt, cmp);
        for(int it=0; it<cnt; ++it) {
            int x=e[it].x, y=e[it].y, w=e[it].w;
            if(w<d[x][y]) {
                ++tot;
                printf("%d %d %d\n", x, y, w);
                d[x][y]=d[y][x]=w;
                for(int i=1; i<=n; ++i) {
                    for(int j=1; j<=n; ++j) {
                        d[i][j]=min(d[i][j], min(d[i][x]+d[x][j], d[i][y]+d[y][j]));
                    }
                }
            }
        }
        for(; tot<=m; ++tot) {
            printf("%d %d %d\n", 1, 1, 1);
        }
    }
}
namespace four {
    const int N=55005;
    vector<int> a[N];
    void work() {
        int n, root;
        scanf("%d%d", &n, &root);
        printf("%d %d\n", n, root);
        int csz=0, sz=pow(n, (double)2/3);
        for(int i=1; i<=n; ++i) {
            int blc;
            scanf("%d", &blc);
            csz+=a[blc].empty();
            a[blc].push_back(i);
        }
        int j, rt, na;
        for(j=0, na=a[csz].size(); j<na; ++j) {
            if(a[csz][j]==root) {
                swap(a[csz][j], a[csz][0]);
                break;
            }
        }
        for(int i=csz; i>=1; --i) {
            rt=a[i][0], j=1, na=a[i].size();
            for(; j<sz-1 && j<na; ++j) {
                printf("%d %d\n", a[i][j-1], a[i][j]);
            }
            if(j<na) {
                printf("%d %d\n", a[i][j++], root);
            }
            for(; j<sz*2-1 && j<na; ++j) {
                printf("%d %d\n", a[i][j-1], a[i][j]);
            }
            if(j<na) {
                printf("%d %d\n", a[i][j++], root);
            }
            for(; j<na; ++j) {
                printf("%d %d\n", a[i][j-1], a[i][j]);
            }
            if(root!=rt) {
                printf("%d %d\n", root, rt);
            }
        }
    }
}
namespace five {
    const int N=100015;
    struct E {
        int l, r, k, w;
    }e[N];
    bool cmp(const E &a, const E &b) {
        if(a.w==-1) {
            return 0;
        }
        if(b.w==-1) {
            return 1;
        }
        return a.w<b.w;
    }
    int a[N], K[N], vis[N], left, right;
    void work() {
        int n, t;
        scanf("%d%d", &n, &t);
        printf("%d %d\n", n, t);
        left=1; 
        right=n;
        int len=n/t, tot=0;
        for(int i=0; i<t; ++i) {
            int w;
            scanf("%d%d", &K[i], &w);
            if(w==-1) {
                continue;
            }
            e[tot].l=i*len+1, e[tot].r=i*len+len;
            e[tot].k=len-K[i]+1;
            e[tot].w=w;
            ++tot;
        }
        sort(e, e+tot, cmp);
        for(int i=0; i<tot; ++i) {
            int l=e[i].l, k=e[i].k, w=e[i].w;
            for(int j=1; j<k; ++j, ++l) {
                while(vis[left]) {
                    ++left;
                }
                a[l]=left;
                vis[left]=1;
                ++left;
            }
            a[l]=w;
            vis[w]=1;
        }
        for(int i=tot-1; i>=0; --i) {
            int r=e[i].r, k=e[i].k;
            for(int j=0; j<(len-k); ++j, --r) {
                while(vis[right]) {
                    --right;
                }
                a[r]=right;
                vis[right]=1;
                --right;
            }
        }
        for(int i=1; i<=n; ++i) {
            if(a[i]) {
                continue;
            }
            while(vis[right]) {
                --right;
            }
            a[i]=right;
            --right;
        }
        for(int i=1; i<=n; ++i) {
            printf("%d ", a[i]);
        }
        for(int i=0; i<t; ++i) {
            printf("%d ", K[i]);
        }
    }
}
int main() {
    int C;
    scanf("%d", &C);
    printf("%d\n", C);
    if(C<20) one::work();
    else if(C<40) two::work();
    else if(C<60) three::work();
    else if(C<80) four::work();
    else five::work();
    return 0;
}
相關文章
相關標籤/搜索