Hướng dẫn giải của Động viên đàn bò
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của ladpro98
#include <bits/stdc++.h> #define ii pair<int, int> #define iii pair<int, ii> #define X first #define Y second const int N = 10100; const int M = 100010; using namespace std; int lab[N], C[N]; iii e[M]; int n, m; int root(int u) {return (lab[u] <= 0) ? u : (lab[u] = root(lab[u]));} void unite(int u, int v) {if (lab[u] > lab[v]) swap(u, v); if (lab[u] == lab[v]) lab[u]--; lab[v] = u;} int main() { ios :: sync_with_stdio(0); cin.tie(); cin >> n >> m; int u, v, L; for(int i = 1; i <= n; i++) cin >> C[i]; for(int i = 1; i <= m; i++) { cin >> u >> v >> L; e[i] = iii(C[u] + C[v] + L + L, ii(u, v)); } sort(e + 1, e + 1 + m); int cnt = 0, res = *min_element(C + 1, C + 1 + n); for(int i = 1; i <= m; i++) { u = root(e[i].Y.X); v = root(e[i].Y.Y); if (u != v) { res += e[i].X; unite(u, v); cnt++; } if (cnt == n - 1) break; } cout << res << endl; return 0; }
Code mẫu của RR
{ PROG: cheer LANG: PASCAL ID: invinci3 } const FINP=''; FOUT=''; MAXN=10011; MAXM=100011; var cost,father:array[1..MAXN] of longint; eu,ev,ec:array[1..MAXM] of longint; kq,n,m:longint; procedure inp; var f:text; i,u,v,c:longint; begin assign(f,FINP); reset(f); read(f,n,m); kq:=maxlongint; for i:=1 to n do begin read(f,cost[i]); if kq>cost[i] then kq:=cost[i]; end; for i:=1 to m do begin read(f,u,v,c); eu[i]:=u; ev[i]:=v; ec[i]:=2*c+cost[u]+cost[v]; end; close(f); end; procedure swap(var a,b:longint); inline; var temp:longint; begin temp:=a; a:=b; b:=temp; end; procedure sort(l,r:longint); inline; var i,j,mid:longint; begin i:=l; j:=r; mid:=ec[l+random(r-l+1)]; repeat while ec[i]<mid do inc(i); while ec[j]>mid do dec(j); if i<=j then begin swap(eu[i],eu[j]); swap(ev[i],ev[j]); swap(ec[i],ec[j]); inc(i); dec(j); end; until i>j; if i<r then sort(i,r); if l<j then sort(l,j); end; procedure ans; var f:text; begin assign(f,FOUT); rewrite(f); writeln(f,kq); close(f); end; function getRoot(u:longint):longint; begin if father[u]<0 then getRoot:=u else begin father[u]:=getRoot(father[u]); getRoot:=father[u]; end; end; procedure union(r1,r2:longint); var x:longint; begin x:=father[r1]+father[r2]; if father[r1]<father[r2] then begin father[r1]:=x; father[r2]:=r1; end else begin father[r2]:=x; father[r1]:=r2; end; end; procedure solve; var i,count,r1,r2:longint; begin for i:=1 to n do father[i]:=-1; count:=0; for i:=1 to m do begin r1:=getRoot(eu[i]); r2:=getRoot(ev[i]); if r1=r2 then continue; inc(count); inc(kq,ec[i]); if count=n-1 then break; union(r1,r2); end; end; begin inp; sort(1,m); solve; ans; end.
Code mẫu của hieult
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> //#include <conio.h> using namespace std; #define MAX(a,b) ((a>b)?a:b) #define CLEAR(A,N) (memset(A,0,(N)*sizeof(A[0]))) const int maxEdgeSize = 200005; typedef struct{ int x,y,cost; }graph; graph v[maxEdgeSize]; int ar[maxEdgeSize]; int findSet(int i){ while(ar[i]!=i) i = ar[i]; return i; } void makeUnion(int a,int p1,int b, int p2){ int x = MAX(p1,p2); ar[a] = x; ar[b] = x; ar[p1] = x; ar[p2] = x; } int adjustUsingUnionFind(int a,int b) { if(ar[a] == -1) ar[a] = a; if(ar[b] == -1) ar[b] = b; int p1 = findSet(a); int p2 = findSet(b); if(p1!=p2){ makeUnion(a,p1,b,p2); return 1; } else return 0; } bool operator < (graph a, graph b) { return a.cost < b.cost; } int main() { //freopen("QBMST.in","r",stdin); int m,n,i,minimumCost,minn = 1000000,u[20001]; scanf("%d %d",&m,&n); for(int i = 1;i<=m;i++) { scanf("%d",&u[i]); if(u[i]<minn) minn = u[i]; } // printf("1"); for(int i = 0;i<n;i++) { scanf("%d %d %d",&v[i].x,&v[i].y,&v[i].cost); v[i].cost = 2*v[i].cost+u[v[i].x]+u[v[i].y]; } //printf("2"); sort(v,v+n); for(int i = 0;i<=m;i++) ar[i] = -1; minimumCost = 0; // printf("3"); for(int i = 0;i<n;i++) { if(adjustUsingUnionFind(v[i].x,v[i].y)==1) { minimumCost+= v[i].cost; //printf("%d\n",v[i].cost); } } printf("%d",minimumCost+minn); //getch(); }
Code mẫu của ll931110
program CHEER; const input = ''; output = ''; maxn = 10000; maxp = 100000; type edge = record u,v,cost: longint; end; var e: array[1..maxp] of edge; a,pr,rank: array[1..maxn] of longint; n,p: longint; res: longint; procedure init; var f: text; i: longint; begin assign(f, input); reset(f); readln(f, n, p); for i := 1 to n do read(f, a[i]); for i := 1 to p do begin read(f, e[i].u, e[i].v, e[i].cost); e[i].cost := 2 * e[i].cost + a[e[i].u] + a[e[i].v]; end; close(f); end; procedure swap(var x,y: edge); var z: edge; begin z := x; x := y; y := z; end; procedure sort(l,h: longint); var i,j: longint; t: longint; begin if l >= h then exit; i := l; j := h; t := e[random(h - l + 1) + l].cost; repeat while e[i].cost < t do inc(i); while e[j].cost > t do dec(j); if i <= j then begin if i < j then swap(e[i],e[j]); inc(i); dec(j); end; until i > j; sort(l,j); sort(i,h); end; procedure makeset(i: longint); begin pr[i] := i; rank[i] := 0; end; function root(x: longint): longint; begin if x <> pr[x] then pr[x] := root(pr[x]); root := pr[x]; end; procedure link(x,y: longint); begin if rank[x] > rank[y] then pr[y] := x else pr[x] := y; if rank[x] = rank[y] then inc(rank[y]); end; procedure union(x,y: longint); begin link(root(x),root(y)); end; procedure Kruskal; var i,cc: longint; begin cc := 0; res := 0; for i := 1 to n do if (res = 0) or (res > a[i]) then res := a[i]; for i := 1 to n do makeset(i); for i := 1 to p do begin if cc = n - 1 then break; if root(e[i].u) <> root(e[i].v) then begin res := res + e[i].cost; union(e[i].u,e[i].v); inc(cc); end; end; end; procedure printresult; var f: text; begin assign(f, output); rewrite(f); writeln(f, res); close(f); end; begin init; sort(1,p); Kruskal; printresult; end.
Code mẫu của skyvn97
#include<bits/stdc++.h> #define MAXV 10101 #define MAXE 200200 using namespace std; typedef long long ll; struct edge { int u,v,c; edge(){} edge(const int &_u,const int &_v,const int &_c) { u=_u;v=_v;c=_c; } bool operator < (const edge &x) const { return (c<x.c); } }; int t[MAXV]; int up[MAXV]; edge g[MAXE]; int n,m,mv; int min(const int &x,const int &y) { if (x<y) return (x); else return (y); } int find(const int &x) { if (up[x]<0) return (x); up[x]=find(up[x]); return (up[x]); } void join(const int &a,const int &b) { int x=find(a); int y=find(b); if (x==y) return; up[y]=x; } void loadgraph(void) { scanf("%d",&n); scanf("%d",&m); int i,u,v,c; mv=(int)1e9; for (i=1;i<=n;i=i+1) { scanf("%d",&t[i]); mv=min(mv,t[i]); } for (i=1;i<=m;i=i+1) { scanf("%d",&u); scanf("%d",&v); scanf("%d",&c); g[i]=edge(u,v,2*c+t[u]+t[v]); } sort(&g[1],&g[m+1]); //for (i=1;i<=m;i=i+1) printf("%d %d %d\n",g[i].u,g[i].v,g[i].c); } void kruskal(void) { int i; ll res=(ll)mv; for (i=0;i<=n;i=i+1) up[i]=-1; for (i=1;i<=m;i=i+1) if (find(g[i].u)!=find(g[i].v)) { //printf("Accept %d %d %d\n",g[i].u,g[i].v,g[i].c); res+=g[i].c; join(g[i].u,g[i].v); } printf("%lld",res); } int main(void) { //freopen("tmp.txt","r",stdin); loadgraph(); kruskal(); return 0; }
Bình luận