Hướng dẫn giải của CENTRE


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.

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 happyboy99x

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<vii> vvii;
typedef vector<int> vi;
typedef vector<vi> vvi;

#define sz(a) int((a).size())
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c,i) for(typeof((c).begin()) i = (c).begin(), _e = (c).end(); i != _e; ++i)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define rep(i,n) for(int i = 0, _n = (n); i < _n; ++i)
#define repd(i,n) for(int i = (n)-1; i >= 0; --i )
#define fo(i,a,b) for(int i = (a), _b = (b); i <= _b; ++i)
#define fod(i,a,b) for(int i = (a), _b = (b); i >= _b; --i)

#define INF 1000000000
#define N 30005
typedef long long LL;

int d1[N], d2[N], n, m;
LL c1[N], c2[N];
vvii g;

void dijkstra(vvii&g, int s, int *d, LL *c) {
    fill(d,d+n,INF); d[s] = 0; c[s] = 1;
    priority_queue< ii, vii, greater<ii> > qu;
    qu.push(ii(0,s));
    while(!qu.empty()) {
        int u = qu.top().se, du = qu.top().fi; qu.pop();
        if(du > d[u]) continue;
        tr(g[u],it) {
            int v = it->fi, l = it->se;
            if( du + l < d[v] ) {
                qu.push(ii(d[v] = du+l,v));
                c[v] = c[u];
            } else if( du + l == d[v] ) c[v] += c[u];
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen( "input.txt", "r", stdin );
    //freopen( "output.txt", "w", stdout );
#endif
    scanf("%d%d",&n,&m); g.resize(n);
    rep(i,m) {
        int u, v, l; scanf("%d%d%d",&u,&v,&l);
        g[--u].pb(ii(--v,l)); g[v].pb(ii(u,l));
    }
    dijkstra(g, 0, d1, c1);
    dijkstra(g, n-1, d2, c2);
    vi res;
    rep(i,n)
        if(!(d1[i]+d2[i]==d1[n-1] && c1[i]*c2[i]==c1[n-1])) res.pb(i+1);
    printf("%d\n",sz(res));
    tr(res,it) printf("%d\n",*it);
    return 0;
}

Code mẫu của ladpro98

{$MODE OBJFPC}
program centre28;
uses    math;
type    e=record
        v,w,link:longint;
        end;
const   maxn=30003;
        maxm=200005;
        oo=trunc(1e9);
        fi='';
var     adj:array[1..maxm] of e;
        head,pos,h:array[1..maxn] of longint;
        d,way:array[1..2,1..maxn] of longint;
        n,m,mm,nh:longint;

procedure input;
var     inp:text;
        i,x,y,w:longint;
begin
        assign(inp,fi);reset(inp);
        readln(inp,n,mm);
        for i:=1 to mm do
        begin
                readln(inp,x,y,w);
                inc(m);
                adj[m].v:=y;
                adj[m].w:=w;
                adj[m].link:=head[x];
                head[x]:=m;
                inc(m);
                adj[m].v:=x;
                adj[m].w:=w;
                adj[m].link:=head[y];
                head[y]:=m;
        end;
        close(inp);
end;

procedure update(dir,u:longint);
var     c,p:longint;
begin
        c:=pos[u];
        if c=0 then
        begin
                inc(nh);
                c:=nh;
        end;
        repeat
                p:=c shr 1;
                if (p=0) or (d[dir,h[p]]<=d[dir,u]) then break;
                h[c]:=h[p];
                pos[h[c]]:=c;
                c:=p;
        until false;
        h[c]:=u;
        pos[u]:=c;
end;

function extract(dir:longint):longint;
var     v,p,c:longint;
begin
        result:=h[1];
        v:=h[nh];
        dec(nh);
        p:=1;
        repeat
                c:=p shl 1;
                if (c<nh) and (d[dir,h[c+1]]<d[dir,h[c]]) then inc(c);
                if (c>nh) or (d[dir,h[c]]>=d[dir,v]) then break;
                h[p]:=h[c];
                pos[h[p]]:=p;
                p:=c;
        until false;
        h[p]:=v;
        pos[v]:=p;
end;


procedure dijkstra(source,dir:longint);
var     u,i:longint;
        v:e;
begin
        for i:=1 to n do d[dir,i]:=oo;
        for i:=1 to n do pos[i]:=0;
        d[dir,source]:=0;
        way[dir,source]:=1;
        nh:=0;
        update(dir,source);
        repeat
                u:=extract(dir);
                i:=head[u];
                while i>0 do
                begin
                        v:=adj[i];
                        if d[dir,v.v]>d[dir,u]+v.w then
                        begin
                                d[dir,v.v]:=d[dir,u]+v.w;
                                update(dir,v.v);
                                way[dir,v.v]:=way[dir,u];
                        end
                        else
                        if d[dir,v.v]=d[dir,u]+v.w then
                                inc(way[dir,v.v],way[dir,u]);
                        i:=v.link;
                end;
        until nh=0;
end;

procedure process;
var     i,res:longint;
        ver:array[1..maxn] of longint;
begin
        res:=0;
        for i:=2 to n-1 do
        if (d[1,i]+d[2,i]>d[1,n])
        or ((d[1,i]+d[2,i]=d[1,n]) and (way[1,i]*way[2,i]<way[1,n])) then
        begin
                inc(res);
                ver[res]:=i;
        end;
        writeln(res);
        for i:=1 to res do
        writeln(ver[i]);
end;

begin
        input;
        dijkstra(1,1);
        dijkstra(n,2);
        process;
end.

Code mẫu của RR

{$R+,Q+}
const
  FINP='';
  FOUT='';
  MAXN=30000;
  oo=1000000000;
type
  list=^node;
  node=record u,c:longint; next:list; end;
  mang=array[1..MAXN] of int64;
var
  p:list;
  ke:array[1..MAXN] of list;
  hsize,n:longint;
  d,h,hpos:array[1..MAXN] of longint;
  f,g:mang;
procedure add(u,c:longint; var a:list);
var
  p:list;
begin
  new(p); p^.u:=u; p^.c:=c; p^.next:=a; a:=p;
end;
procedure inp;
var
  f:text;
  i,m,u,v,c:longint;
begin
  assign(f,FINP); reset(f);
  read(f,n,m);
  for i:=1 to n do ke[i]:=nil;
  for i:=1 to m do
    begin
      read(f,u,v,c);
      if u=v then continue;
      add(v,c,ke[u]);
      add(u,c,ke[v]);
    end;
  close(f);
end;
procedure swap(var a,b:longint);
var
  temp:longint;
begin
  temp:=a; a:=b; b:=temp;
end;
procedure downHeap(i:longint);
var
  j:longint;
begin
  j:=i shl 1;
  while (j<=hsize) do
    begin
      if (j<hsize) and (d[h[j+1]]<d[h[j]]) then inc(j);
      if d[h[j]]<d[h[i]] then
        begin
          swap(hpos[h[i]],hpos[h[j]]);
          swap(h[i],h[j]);
        end;
      i:=j; j:=i shl 1;
    end;
end;
procedure upHeap(i:longint);
var
  j:longint;
begin
  j:=i shr 1;
  while (i>1) and (d[h[i]]<d[h[j]]) do
    begin
      swap(hpos[h[i]],hpos[h[j]]);
      swap(h[i],h[j]);
      i:=j; j:=i shr 1;
    end;
end;
procedure push(u:longint);
begin
  inc(hsize); h[hsize]:=u; hpos[u]:=hsize;
  upHeap(hsize);
end;
procedure pop(var u:longint);
begin
  u:=h[1]; hpos[u]:=0;
  swap(h[1],h[hsize]);
  hpos[h[1]]:=1; dec(hsize);
  downHeap(1);
end;
procedure dijkstra;
var
  u,v,c:longint;
  p:list;
begin
  while hsize>0 do
    begin
      pop(u);
      p:=ke[u];
      while p<>nil do
        begin
          v:=p^.u; c:=p^.c; p:=p^.next;
          if d[v]>d[u]+c then
            begin
              d[v]:=d[u]+c;
              if hpos[v]=0 then push(v)
              else upHeap(hpos[v]);
            end;
        end;
    end;
end;
procedure ans;
var
  fo:text;
  count,i:longint;
begin
  assign(fo,FOUT); rewrite(fo);
  count:=0;
  for i:=2 to n-1 do
    if (f[i]*g[i]<>f[n]) or (f[i]=-1) or (g[i]=-1) then inc(count);
  writeln(fo,count);
  for i:=2 to n-1 do
    if (f[i]*g[i]<>f[n]) or (f[i]=-1) or (g[i]=-1) then writeln(fo,i);
  close(fo);
end;
procedure dfs1(u:longint); inline;
var
  p:list;
  v,c:longint;
begin
  if f[u]<>-1 then exit;
  f[u]:=0;
  p:=ke[u];
  while p<>nil do
    begin
      v:=p^.u; c:=p^.c;
      p:=p^.next;
      if d[v]+c=d[u] then
        begin
          dfs1(v);
          f[u]:=f[u]+f[v];
        end;
    end;
end;
procedure dfs2(u:longint);
var
  p:list;
  v,c:longint;
begin
  if g[u]<>-1 then exit;
  g[u]:=0;
  p:=ke[u];
  while p<>nil do
    begin
      v:=p^.u; c:=p^.c;
      p:=p^.next;
      if d[v]+c=d[u] then
        begin
          dfs2(v);
          g[u]:=g[u]+g[v];
        end;
    end;
end;
procedure solve;
var
  u:longint;
begin
  for u:=1 to n do d[u]:=oo;
  for u:=1 to n do f[u]:=-1;
  hsize:=1; h[1]:=1; d[1]:=0; hpos[1]:=1;
  f[1]:=1;
  dijkstra;
  dfs1(n);
  for u:=1 to n do d[u]:=oo;
  for u:=1 to n do g[u]:=-1;
  fillchar(hpos,sizeof(hpos),0);
  hsize:=1; h[1]:=n; d[n]:=0; hpos[n]:=1;
  g[n]:=1;
  dijkstra;
  dfs2(1);
end;
begin
  inp;
  solve;
  ans;
end.

Code mẫu của ll931110

{$MODE DELPHI}
Program CENTRE28;
        Type
              vertex = array[1..30001] of longint;
                edge = array[0..200000] of longint;
              select = array[1..30000] of boolean;
        Const
                input  = '';
                output = '';
                   max = 10000000000000;
        Var
                               n,m,nHeap: longint;
                             adj,adjcost: edge;
                        pos,heap,h,queue: vertex;
                    n1,nn,d1,dn,d,numway: array[1..30001] of int64;
                                   x,y,c: array[1..100000] of longint;
                              free,check: select;

Procedure LoadGraph;
          Var
                f: text;
                i: longint;
          Begin
                Assign(f, input);
                        Reset(f);

                Fillchar(h, sizeof(h), 0);

                Readln(f, n, m);
                For i:= 1 to m do
                        Begin
                                Readln(f, x[i], y[i], c[i]);
                                inc(h[x[i]]);
                                inc(h[y[i]]);
                        End;
                Close(f);

                For i:= 2 to n do h[i]:= h[i] + h[i - 1];
                For i:= 1 to m do
                        Begin
                                adj[h[x[i]]]:= y[i];
                                adjcost[h[x[i]]]:= c[i];
                                dec(h[x[i]]);

                                adj[h[y[i]]]:= x[i];
                                adjcost[h[y[i]]]:= c[i];
                                dec(h[y[i]]);
                        End;
                h[n + 1]:= 2 * m;
          End;

procedure Update(v: Integer);
var
  parent, child: Integer;
begin
  child := Pos[v];
  if child = 0 then
    begin
      Inc(nHeap); child := nHeap;
    end;
  parent := child div 2;
  while (parent > 0) and (d[heap[parent]] > d[v]) do
    begin
      heap[child] := heap[parent];
      Pos[heap[child]] := child;
      child := parent;
      parent := child div 2;
    end;
  heap[child] := v;
  Pos[v] := child;
end;

function Pop: Integer;
var
  r, c, v: Integer;
begin
  Pop := heap[1];
  v := heap[nHeap];
  Dec(nHeap);
  r := 1;
  while r * 2 <= nHeap do
    begin
      c := r * 2;
      if (c < nHeap) and (d[heap[c + 1]] < d[heap[c]]) then Inc(c);
      if d[v] <= d[heap[c]] then Break;
      heap[r] := heap[c];
      Pos[heap[r]] := r;
      r := c;
    end;
  heap[r] := v;
  Pos[v] := r;
end;

Procedure Dijkstra(s: integer);
          Var
                i,u,iv,v: longint;
          Begin
                Fillchar(pos, sizeof(pos), 0);
                Fillchar(free, sizeof(free), true);

                Fillchar(numway, sizeof(numway), 0);
                numway[s]:= 1;

                For i:= 1 to n do d[i]:= max;
                d[s]:= 0;
                nHeap:= 0;

                Update(s);
                Repeat
                        u:= pop;
                        If u = 0 then break;
                        free[u]:= false;

                        For iv:= h[u] + 1 to h[u + 1] do
                           Begin
                                v:= adj[iv];
                                If free[v] then
                                   If d[v] > d[u] + adjcost[iv] then
                                        Begin
                                                d[v]:= d[u] + adjcost[iv];
                                                numway[v]:= numway[u];
                                                Update(v);
                                        End
                                   else if d[v] = d[u] + adjcost[iv] then
                                        numway[v]:= numway[v] + numway[u];
                           End;
                Until nHeap = 0;
          End;

Procedure printresult;
          Var
                  f: text;
                k,i: longint;
          Begin
                Dijkstra(1);
                d1:= d;
                n1:= numway;

                Dijkstra(n);
                dn:= d;
                nn:= numway;

                Assign(f, output);
                        Rewrite(f);

                Fillchar(free, sizeof(free), false);
                k:= 0;

                For i:= 2 to n - 1 do
                  if (d1[i] + dn[i] <> d1[n])
                        or (int64(n1[i] * nn[i]) <> n1[n]) then
                            Begin
                                inc(k);
                                free[i]:= true;
                            End;

                Writeln(f, k);
                For i:= 2 to n - 1 do if free[i] then writeln(f, i);

                Close(f);
          End;

Begin
        LoadGraph;
        printresult;
End.

Code mẫu của skyvn97

#include<cstdio>
#include<queue>
#include<vector>
#define MAX   30303
#define INF   1e9
#define v   second
#define w   first
using namespace std;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef priority_queue<ii,vii,greater<ii> > pq;
int m,n,r;
vii g[MAX];
int d[7][MAX];
int c[7][MAX];
bool a[MAX];
void loadgraph(void) {
    int i,u,v,w;
    scanf("%d",&n);
    scanf("%d",&m);
    for (i=1;i<=m;i=i+1) {
        scanf("%d",&u);
        scanf("%d",&v);
        scanf("%d",&w);
        g[u].push_back(ii(w,v));
        g[v].push_back(ii(w,u));
    }
    for (i=1;i<=n;i=i+1) {
        d[0][i]=INF;
        d[1][i]=INF;
        c[0][i]=0;
        c[1][i]=0;
    }       
}
void dijkstra(int s) {
    pq q=pq();
    ii p;
    int i,u,w;
    d[s%n][s]=0;
    c[s%n][s]=1;
    q.push(ii(0,s));
    while (!q.empty()) {
        p=q.top();q.pop();
        u=p.v;
        w=p.w;
        for (i=0;i<g[u].size();i=i+1) {
            if (w+g[u][i].w==d[s%n][g[u][i].v]) c[s%n][g[u][i].v]+=c[s%n][u];
            if (w+g[u][i].w<d[s%n][g[u][i].v]) {
                d[s%n][g[u][i].v]=w+g[u][i].w;
                c[s%n][g[u][i].v]=c[s%n][u];
                q.push(ii(d[s%n][g[u][i].v],g[u][i].v));
            }
        }
    }   
}
void process(void) {
    dijkstra(1);
    dijkstra(n);
    r=0;
    int i;
    for (i=2;i<n;i=i+1) {
        if (d[1][i]+d[0][i]>d[1][n]) {
            r=r+1;
            a[i]=true;
        }       
        else {
            if (c[1][i]*c[0][i]<c[1][n]) {
                r=r+1;
                a[i]=true;
            }
            else a[i]=false;
        }
    }       
    printf("%d\n",r);
    for (i=2;i<n;i=i+1)
        if (a[i]) printf("%d\n",i);
}
int main(void) {
    loadgraph();
    process();
    return 0;
}

Code mẫu của khuc_tuan

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;

const int MAX = 30001;

struct Node {
    int v, x, d;
    Node *next;
    Node() {}
    Node(int v, int x, int d) {
        this->v = v;
        this->x = x;
        this->d = d;
        this->next = NULL;
    }
};

int inf, n, m, dem;
int d[MAX], d2[MAX];
Node *ke[MAX];
int low[MAX], num[MAX], fa[MAX];
bool khop[MAX], mark[MAX], vs[MAX];

void add( Node * & p, Node * q) {
    Node * tmp = p;
    p = q;
    q->next = tmp;
}

void dfs( int i ) {
    num[i] = dem++;
    low[i] = num[i];
    vs[i] = true;
    for(Node * p = ke[i]; p!=NULL; p = p->next) {
        int j = p->v;
        int z = p->d;
        /*if(d[j]==d[i]+z) {
            fa[j] = i;
            dfs(j);
            low[i] <?= low[j];
        }
        else if(d[j]+z==d[i] && j!=fa[i]) {
            low[i] <?= num[j];
        }*/
        if(!mark[j]) continue;
        if(d[j]==d[i]+z || d[i]==d[j]+z) {
            if(!vs[j]) {
                fa[j] = i;
                dfs(j);
                low[i] <?= low[j];
            }
            else if(j!=fa[i]) {
                low[i] <?= num[j];
            }
        }
    }
    if(fa[i]>0) {
        int fi = fa[i];
        if(low[i]>=num[fi]) khop[fi] = true;
    }
}

void bfs( int st, int d[MAX]) {
    queue<int> q;
    q.push(st);
    memset( d, 0x3f, sizeof(d2));
    inf = d[0];
    d[st] = 0;
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(Node * p = ke[u]; p!=NULL; p = p->next) {
            int v = p->v;
            int z = p->d;
            if(d[v]>d[u]+z) {
                d[v] = d[u] + z;
                q.push(v);
            }
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i=0;i<m;++i) {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        add( ke[x], new Node(y, x^y, z));
        add( ke[y], new Node(x, x^y, z));
    }
    bfs( 1, d);
    bfs( n, d2);
    for(int i=1;i<=n;++i) if(d[i]+d2[i] == d[n]) mark[i] = true;
    int res = 0;
    dfs(1);
    for(int i=2;i<n;++i) if(!khop[i] || !mark[i]) ++res;
    printf("%d\n", res);
    for(int i=2;i<n;++i) if(!khop[i] || !mark[i]) printf("%d\n", i);
    //system("pause");
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.