Hướng dẫn giải của Vòng đua F1
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 flashmt
const fi=''; maxn=10010; maxm=100010; var re,n,m:longint; b:array[0..maxm,0..2] of longint; cha,sl:array[1..maxn] of longint; procedure rf; var i,j:longint; begin read(n,m); for i:=1 to m do for j:=0 to 2 do read(b[i,j]); for i:=1 to n do begin cha[i]:=i; sl[i]:=1; end; end; procedure sort(l,r:longint); var i,j,x:longint; begin i:=l; j:=r; x:=b[(i+j) shr 1,2]; repeat while b[i,2]>x do i:=i+1; while b[j,2]<x do j:=j-1; if i<=j then begin b[0]:=b[i]; b[i]:=b[j]; b[j]:=b[0]; i:=i+1; j:=j-1; end; until i>j; if i<r then sort(i,r); if l<j then sort(l,j); end; function find(x:longint):longint; begin if cha[x]=x then find:=x else begin cha[x]:=find(cha[x]); find:=cha[x]; end; end; procedure pr; var i,j,x,y,xx,yy,dem:longint; begin sort(1,m); for i:=1 to m do begin x:=b[i,0]; y:=b[i,1]; xx:=find(x); yy:=find(y); if xx=yy then re:=re+b[i,2] else begin dem:=dem+1; if sl[xx]>=sl[yy] then begin cha[yy]:=xx; sl[xx]:=sl[xx]+sl[yy]; end else begin cha[xx]:=yy; sl[yy]:=sl[yy]+sl[xx]; end; if dem=n-1 then break; end; end; for j:=i+1 to m do re:=re+b[j,2]; writeln(re); end; begin assign(input,fi); reset(input); rf; pr; close(input); end.
Code mẫu của happyboy99x
#include<cstdio> #include<vector> #include<algorithm> #include<functional> using namespace std; #define TR(v,i) for(typeof((v).begin())i=(v).begin();i!=(v).end();++i) const int N = 1e4 + 7; int n, m, r[N], l[N]; vector<vector<pair<int, int> > > g; bool vst[N]; void initSet(int n) { for(int i = 0; i < n; ++i) r[i] = i; } int getSet(int u) { return u == r[u] ? u : r[u] = getSet(r[u]); } void enter() { scanf("%d%d",&n,&m); g.resize(n); for(int i = 0; i < m; ++i) { int u, v, w; scanf("%d%d%d",&u,&v,&w); g[--u].push_back(make_pair(--v, w)); g[v].push_back(make_pair(u, w)); } } int dfs(const int &u, vector<pair<int, pair<int, int> > > &edge, int &sumEdge) { int res = 1; vst[u] = true; TR(g[u], it) { int v = it->first, w = it->second; if(!vst[v]) { edge.push_back(make_pair(w, make_pair(u, v))); sumEdge += w; l[v] = l[u] + 1; res += dfs(v, edge, sumEdge); } else if(l[v] < l[u] - 1) { edge.push_back(make_pair(w, make_pair(u, v))); sumEdge += w; } } return res; } void solve() { int res = 0; initSet(n); for(int u = 0; u < n; ++u) if(!vst[u]) { vector<pair<int, pair<int, int> > > edge; l[u] = 0; int n = dfs(u, edge, res), cnt = 1; sort(edge.begin(), edge.end(), greater<pair<int, pair<int, int> > >()); TR(edge, it) { int u = it->second.first, v = it->second.second, w = it->first; if(getSet(u) != getSet(v)) { res -= w; r[r[u]] = r[v]; if(++cnt == n) break; } } } printf("%d\n", res); } int main() { enter(); solve(); return 0; }
Code mẫu của ladpro98
{$MODE OBJFPC} program nkracing; uses math; type e=record x,y,w:longint; end; const maxn=10004; maxm=100005; fi=''; var res,n,m:longint; a:array[1..maxm] of e; lab:array[1..maxn] of longint; check:array[1..maxm] of boolean; procedure input; var inp:text; i:longint; begin assign(inp,fi);reset(inp); readln(inp,n,m); for i:=1 to m do readln(inp,a[i].x,a[i].y,a[i].w); close(inp); end; procedure sort(l,r:longint); var p,i,j:longint; t:e; begin if l>=r then exit; i:=l;j:=r; p:=a[random(r-l+1)+l].w; repeat while a[i].w>p do inc(i); while a[j].w<p do dec(j); if i<=j then begin if i<j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; end; inc(i);dec(j); end; until i>j; sort(l,j);sort(i,r); end; function root(u:longint):longint; begin if lab[u]<=0 then exit(u); result:=root(lab[u]); lab[u]:=result; end; procedure union(u,v:longint); begin if lab[u]<lab[v] then lab[v]:=u else begin if lab[u]=lab[v] then dec(lab[v]); lab[u]:=v; end; end; procedure kruskal; var i,x,y,c:longint; begin sort(1,m); for i:=1 to m do begin x:=root(a[i].x); y:=root(a[i].y); if x<>y then begin inc(c); check[i]:=true; union(x,y); end; if c=n-1 then break; end; for i:=1 to m do if not check[i] then inc(res,a[i].w); end; begin input; kruskal; write(res); end.
Code mẫu của RR
//Wishing myself a happy lunar new year with a lot of accept solutions //Written by Nguyen Thanh Trung {$R-,Q-} const FINP=''; FOUT=''; MAXN=10000; MAXM=100000; var m,n,sum,mst:longint; eu,ev,ec:array[1..MAXM] of longint; father:array[1..MAXN] of longint; procedure inp; inline; var f:text; i:longint; begin assign(f,FINP); reset(f); read(f,n,m); for i:=1 to m do read(f,eu[i],ev[i],ec[i]); sum:=0; for i:=1 to m do inc(sum,ec[i]); close(f); end; procedure ans; inline; var f:text; begin assign(f,FOUT); rewrite(f); writeln(f,sum-mst); 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[i+random(j-i+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; function getRoot(u:longint):longint; inline; 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); inline; begin if father[r1]<father[r2] then begin father[r1]:=father[r1]+father[r2]; father[r2]:=r1; end else begin father[r2]:=father[r1]+father[r2]; father[r1]:=r2; end; end; procedure solve; inline; var i,sc,u,v,r1,r2:longint; begin for i:=1 to n do father[i]:=-1; sort(1,m); sc:=0; mst:=0; for i:=1 to m do begin u:=eu[i]; v:=ev[i]; r1:=getRoot(u); r2:=getRoot(v); if r1=r2 then continue; union(r1,r2); inc(sc); inc(mst,ec[i]); if sc=n-1 then break; end; end; begin inp; 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=0,u[20001]; scanf("%d %d",&m,&n); for(int i = 0;i<n;i++) { scanf("%d %d %d",&v[i].x,&v[i].y,&v[i].cost); minimumCost = minimumCost + v[i].cost; v[i].cost = -v[i].cost; } //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); // getch(); }
Code mẫu của ll931110
{$MODE DELPHI} program NKRACING; const input = ''; output = ''; maxn = 10000; maxe = 1000000; var n,e: integer; u,v,cost: array[1..maxe] of integer; pr,rank: array[1..maxn] of integer; tot,tree: integer; procedure init; var f: text; i: integer; begin assign(f, input); reset(f); readln(f, n, e); tot := 0; for i := 1 to e do begin readln(f, u[i], v[i], cost[i]); tot := tot + cost[i]; end; close(f); end; procedure sw(var x,y: integer); var z: integer; begin z := x; x := y; y := z; end; procedure swap(i,j: integer); begin sw(u[i],u[j]); sw(v[i],v[j]); sw(cost[i],cost[j]); end; procedure sort(l,h: integer); var i,j,p: integer; begin if l >= h then exit; i := l; j := h; p := cost[random(h - l + 1) + l]; repeat while cost[i] > p do inc(i); while cost[j] < p do dec(j); if i <= j then begin if i < j then swap(i,j); inc(i); dec(j); end; until i > j; sort(l,j); sort(i,h); end; function root(x: integer): integer; begin if x <> pr[x] then pr[x] := root(pr[x]); root := pr[x]; end; procedure link(x,y: integer); 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 solve; var i,nedge: integer; begin tree := 0; for i := 1 to n do begin pr[i] := i; rank[i] := 0; end; nedge := 0; for i := 1 to e do if root(u[i]) <> root(v[i]) then begin tree := tree + cost[i]; inc(nedge); link(root(u[i]),root(v[i])); end; end; procedure printresult; var f: text; begin assign(f, output); rewrite(f); writeln(f, tot - tree); close(f); end; begin init; sort(1,e); solve; printresult; end.
Code mẫu của skyvn97
#include<cstdio> #include<algorithm> #define MAX 100100 using namespace std; 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 { if (c>x.c) return (true); if (c<x.c) return (false); return (u+v<x.u+x.v); } }; int m,n; edge lst[MAX]; int up[MAX]; int find(int x) { if (up[x]<0) return (x); up[x]=find(up[x]); return (up[x]); } void join(int a,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; for (i=1;i<=n;i=i+1) up[i]=-1; for (i=1;i<=m;i=i+1) { scanf("%d",&u); scanf("%d",&v); scanf("%d",&c); lst[i]=edge(u,v,c); } sort(&lst[1],&lst[m+1]); } void kruskal(void) { int i; int res=0; for (i=1;i<=m;i=i+1) { if (find(lst[i].u)!=find(lst[i].v)) join(lst[i].u,lst[i].v); else res+=lst[i].c; } printf("%d",res); } int main(void) { loadgraph(); kruskal(); return 0; }
Code mẫu của khuc_tuan
#include <iostream> #include <cstdio> using namespace std; int n, m; pair<int, pair<int,int> > a[100010]; int F[10010], result; int main() { scanf("%d%d", &n, &m); for(int i=0;i<m;++i) scanf("%d%d%d", &a[i].second.first, &a[i].second.second, &a[i].first); sort( a, a+m); memset( F, -1, sizeof(F)); for(int i=m-1;i>=0;--i) { int c = a[i].first; int u = a[i].second.first; int v = a[i].second.second; result += c; while(F[u]>=0) u = F[u]; while(F[v]>=0) v = F[v]; //cout << c << endl; if(u==v) continue; result -= c; if(F[u]>=F[v]) swap( u, v); F[u] += F[v]; F[v] = u; } cout << result << endl; //system("pause"); return 0; }
Bình luận