要求給出下面代碼的答案而後構造輸入。
給一個圖, n 個點 m 條邊 q 次詢問,輸出全部點對之間最大權值最小的路徑。c++
把每個詢問的輸出當作一條邊,建一棵最小生成樹。spa
給輸出,要求構造輸入使得用所給代碼運行後獲得的輸出和給出的輸出相同。
所給代碼: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; }