BK Algorithm Club
Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.


BK Algorithm Practice Forum
 
Trang ChínhTrang Chính  Latest imagesLatest images  Tìm kiếmTìm kiếm  Đăng kýĐăng ký  Đăng NhậpĐăng Nhập  

 

 bàn về bài QBAGENTS ( đang bị TLE )

Go down 
4 posters
Tác giảThông điệp
duy
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 11
Join date : 02/12/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime31.01.09 18:58

https://vn.spoj.pl/problems/QBAGENTS/
Bài này mình sử dụng giải thuật sau : lần được xét tất cả những đường đi có độ dài L xuất phát từ S và T(L>=0) (đường đi có thể lập lại cạnh và đỉnh) , xem coi có đường đi nào độ dài L xuất phát từ S và từ L có thể đến được cùng 1 đỉnh không ? . Nếu có thì xuất ra L , nếu không thì làm tiếp bằng cách tăng L. Nếu L> ( 1 giá trị giới hạn nào đó ) thì xuất ra -1.

Độ phức tạp trong trường hợp xấu nhất là O(L * N^2 ) ---> TLE nếu L>3000(cài bằng C++) Exclamation
Trên VNOI có 1 số cá nhân đề xuất chiêu chặn thời gian ( gần tới 1 giây thì break ) , nhưng mình nghĩ trong quá trình cài đặt phải có cài thêm cái gì đó

Có bạn / bác nào đã làm bài này rồi cho mình xin hỗ trợ giải thuật.Cảm ơn nhiều
Về Đầu Trang Go down
NKK
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 13
Join date : 28/12/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime01.02.09 18:34

Bài này vốn là bài thi Olympic Balan nhưng không nhớ là năm bao nhiêu. Giải thuật là BFS rồi chặn số ngày (max=n^2)
Code của em bằng Pascal đây
Code:
const
  N_MAX = 250;

type
  parr = ^tarr;
  tarr = array[1..N_MAX,1..N_MAX] of byte;

  pbuffer = ^tbuffer;
  tbuffer = array[1..N_MAX*N_MAX] of byte;

var
  n, a1, a2 : byte;
  m : word;
  G : array[1..N_MAX] of
          record
            deg : byte;
            next : array[1..N_MAX] of byte;
          end;

procedure read_data;
var
  i, j, k : word;

begin
  readln(n, m);

  for i := 1 to n do
      G[i].deg := 0;

  readln(a1, a2);

  for i := 1 to m do
      begin
        readln(j, k);
        inc( G[j].deg);
        G[j].next[G[j].deg] := k
      end;
end;

procedure compute;
var
  arrs: array[0..1] of parr;
  arr_from, arr_to : byte;
  buffer : array[0..1] of pbuffer;
  nbuffer : array[0..1] of pbuffer;
  buf_size, nbuf_size : word;
  mov_no : word;
  pair, new_pair : array[0..1] of byte;
  i, j : word;
  tmp: pbuffer;
  OK : boolean;
begin
    OK := false;
    arrs[0] := new( parr); arrs[1] := new( parr);
    buffer[0] := new( pbuffer); buffer[1] := new( pbuffer);
    nbuffer[0] := new( pbuffer); nbuffer[1] := new( pbuffer);

    for i := 1 to n do
      for j := 1 to n do
          begin
            arrs[0]^[i][j] := 0;
            arrs[1]^[i][j] := 0
          end;
    arrs[0]^[a1][a2] := 1;

    buf_size := 1; buffer[0]^[1] := a1; buffer[1]^[1] := a2;
    mov_no := 0; arr_from := 1; arr_to := 0;

    repeat
      arr_from := 1 - arr_from; arr_to := 1 - arr_to;
      if arr_to = 1 then inc( mov_no);
      nbuf_size := 0;

      for i := 1 to buf_size do
          begin
            pair[0] := buffer[0]^[i]; pair[1] := buffer[1]^[i];
            new_pair[arr_to] := pair[arr_to];
            for j := 1 to G[pair[arr_from]].deg do
                               
                begin
                  new_pair[arr_from] := G[pair[arr_from]].next[j];
                                                     
                  if arrs[arr_to]^[new_pair[0]][new_pair[1]] = 0 then
                      begin
                        arrs[arr_to]^[new_pair[0]][new_pair[1]] := 1;
                        inc( nbuf_size);
                        nbuffer[0]^[nbuf_size] := new_pair[0];
                        nbuffer[1]^[nbuf_size] := new_pair[1];
                        if ( new_pair[0] = new_pair[1])
                              and  ( arr_to = 0) then
                            OK := true
                      end;
                end;
          end;
      buf_size := nbuf_size;
      tmp := buffer[0]; buffer[0] := nbuffer[0]; nbuffer[0] := tmp;
      tmp := buffer[1]; buffer[1] := nbuffer[1]; nbuffer[1] := tmp
    until OK or ( mov_no > n * n);
      if OK then
      writeln(mov_no)
      else writeln('-1');

    dispose( arrs[0]); dispose( arrs[1]);
    dispose( buffer[0]); dispose( buffer[1]);
    dispose( nbuffer[0]); dispose( nbuffer[1]);
end;


begin
  read_data;
  compute;
end.
Về Đầu Trang Go down
ktuan
dzô THCS
dzô THCS



Tổng số bài gửi : 30
Join date : 02/01/2009

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime01.02.09 19:59

Bai nay nghi la dung duong di ngan nhat gom 2n dinh chu khong phai la n dinh
Because:
-De bai lien quan toi do dai duong di
- So buoc di phai bang nhau giua hai dia diem
Moi a[i,j]..i=1..n;
j=1,2 tuong ung voi chan ,le
a[i,j] do dai ngan nhat di tu s toi i ma ton chan buoc neu j chan va ton le buoc neu j le
Nghi co the lam nhu vay
Ai lam duoc xin hay gui cho ban qua mail: lekhactuanlamson0710
Laughing
Về Đầu Trang Go down
ktuan
dzô THCS
dzô THCS



Tổng số bài gửi : 30
Join date : 02/01/2009

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime01.02.09 20:00

addnick: lekhactuanlamson0710
Về Đầu Trang Go down
duy
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 11
Join date : 02/12/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime04.02.09 8:04

thanks 2 bạn NKK , ktuan đã đóng góp ý kiến . Hy vọng 2 bạn thường xuyên ghé thăm diễn đàn để đáp ứng nhu cầu hỏi bài của các thành viên Idea
bài này , nếu đưa đồ thị ban đầu về đồ thị mới với mỗi đỉnh mới chứa 2 đỉnh nào đó của đồ thị cũ thì sẽ dễ thấy bài này chỉ cần dùng BFS , nhưng mà nếu cài BFS bằng Queue thì có nguy cơ bị TLE.
riêng đoạn code của bạn NKK có thể thay thế đoạn

Code:
until OK or ( mov_no > n*n );
bằng
Code:
 until OK or ( buf_size =0 ) ;
( lúc buf_size==0 thì xem như không thể loang được nữa )
Về Đầu Trang Go down
NKK
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 13
Join date : 28/12/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime04.02.09 12:19

Thay đoạn đấy chạy thử thì nhanh hơn được 0.03 giây so với cách trước. Cũng là một cách cải tiến hay Very Happy
Về Đầu Trang Go down
lenhhoxung
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 29
Join date : 26/11/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime05.02.09 18:49

Bài này tui có ý tưởng thế nào, cũng giống như của Duy nói.
Dùng BFS, tại bước BFS đầu tiên cho 2 đỉnh S, T, ta đưa vào hàng đợi của mỗi đỉnh những đỉnh kề với nó, đó là những đường đi có độ dài bằng 1, 2 hàng đợi này ta sử dụng cấu trúc heap để việc kiểm tra có điểm đến chung hay không được nhanh chóng.
Phân tích thời gian chạy như sau. Tại mỗi giá trị L, BFS cho đỉnh S tốn thời gian O(nlogn), BFS cho đỉnh T tốn thời gian O(nlogn) (do việc insert heap tốn O(logn)), việc xác định đỉnh chung cũng tốn khoảng O(nlogn), vậy một bước BFS và tìm đường đi có đội dài L tốn tổng cộng là O(nlogn),
Độ phức tạp cuối cùng là O(L*nlogn)
Về Đầu Trang Go down
lenhhoxung
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 29
Join date : 26/11/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime05.02.09 18:50

mà mới nghĩ vậy thôi, chưa code, tối về code thừ xem.
Về Đầu Trang Go down
lenhhoxung
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 29
Join date : 26/11/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime05.02.09 21:54

Hình như ý tưởng của mình lởm rùi, sorry vì spam:D
Về Đầu Trang Go down
lenhhoxung
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 29
Join date : 26/11/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime05.02.09 22:46

duy đã viết:
thanks 2 bạn NKK , ktuan đã đóng góp ý kiến . Hy vọng 2 bạn thường xuyên ghé thăm diễn đàn để đáp ứng nhu cầu hỏi bài của các thành viên Idea
bài này , nếu đưa đồ thị ban đầu về đồ thị mới với mỗi đỉnh mới chứa 2 đỉnh nào đó của đồ thị cũ thì sẽ dễ thấy bài này chỉ cần dùng BFS , nhưng mà nếu cài BFS bằng Queue thì có nguy cơ bị TLE.
riêng đoạn code của bạn NKK có thể thay thế đoạn

Code:
until OK or ( mov_no > n*n );
bằng
Code:
 until OK or ( buf_size =0 ) ;
( lúc buf_size==0 thì xem như không thể loang được nữa )
Duy nói rõ về ý tưởng này dckô?
Về Đầu Trang Go down
lenhhoxung
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 29
Join date : 26/11/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime06.02.09 2:00

Mọi ng xem thử code C++ này của mình
Đây là địa chỉ link 20 tests của bài này trên ioicamp http://ioicamp.net/index.php?pkg=down&catid=13&start=20
Code này của mình test đúng hết 20 test này, thời gian chạy lâu nhất là chưa tới ..0.95s/test (dùng hàm đo của C++)
Phương pháp để kiểm tra khi nào cần dừng BFS giống như hướng dẫn trên diễn đàn ioicamp, dùng một mảng visit[i][j] để đánh dấu tại một thời đỉêm nào đó thì người thứ 1 đã tới i, ng thứ 2 đã tới j. Nếu sau một lượt BFS mà kô đánh dấu thêm dc cặp i,j nào thì dừng chương trình return -1.
Code:
#include <stdio.h>
//#include <fstream.h>
//#include <time.h>
#define INF 100000
#define MAX 300
int table[MAX][MAX],i,j,visit[MAX][MAX];
int n,m,s,t,u,v,x,y;
int qu1[500000],f1,r1,qu2[500000],f2,r2;
int mark1[MAX],mark2[MAX];
void push1(int n);
void push2(int n);
void pop1(int &n);
void pop2(int &n);
//int st,en;
main()
{   
    //ifstream fin("agents.inp");
    //fin>>n>>m>>s>>t;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for (i=1;i<=n;++i)
    {
        for (j=1;j<=n;++j)
        {
            table[i][j]=INF;
            visit[i][j]=0;
        }
        table[i][i]=0;
    }
    for (i=1;i<=m;++i)
    {
        //fin>>u>>v;
        scanf("%d%d",&u,&v);
        table[u][v]=1;
    }
    //start=clock();
    f1=f2=1;
    r1=r2=0;
    push1(s);
    push2(t);
    int l=0;
    bool stop;
    do
    {       
        int f,r;
        stop=true;
        f=f1;r=r1;++l;       
        for (i=f;i<=r;++i)
        {
            pop1(u);
            for (j=1;j<=n;++j)
            {
                if (table[u][j]==1)
                {
                    if (mark1[j]!=l)
                    {
                        push1(j);
                        mark1[j]=l;
                    }
                }
            }
        }
        f=f2;r=r2;       
        for (i=f;i<=r;++i)
        {
            pop2(u);
            for (j=1;j<=n;++j)
            {
                if (table[u][j]==1)
                {           
                    if (mark2[j]!=l)
                    {
                        push2(j);
                        mark2[j]=l;
                    }
                    if (mark1[j]==l)
                    {
                        printf("%d\n",l);
                        return 0;
                    }
                }
            }
        }
        for (i=f1;i<=r1;++i)
        {
            for (j=f2;j<=r2;++j)
            {
                if (visit[qu1[i]][qu2[j]]==0)
                {
                    visit[qu1[i]][qu2[j]]=1;
                    stop=false;
                }
            }
        }
        if (stop)
        {
            printf("-1\n");
            return 0;
        }
    } while (1);
    return 0;
}
void push1(int n)
{
    qu1[++r1]=n;
}
void push2(int n)
{
    qu2[++r2]=n;
}
void pop1(int &n)
{
    n=qu1[f1++];
}
void pop2(int &n)
{
    n=qu2[f2++];
}
Về Đầu Trang Go down
duy
bắt đầu sự nghiệp đi học
bắt đầu sự nghiệp đi học



Tổng số bài gửi : 11
Join date : 02/12/2008

bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime06.02.09 12:33

lenhhoxung đã viết:
duy đã viết:
thanks 2 bạn NKK , ktuan đã đóng góp ý kiến . Hy vọng 2 bạn thường xuyên ghé thăm diễn đàn để đáp ứng nhu cầu hỏi bài của các thành viên Idea
bài này , nếu đưa đồ thị ban đầu về đồ thị mới với mỗi đỉnh mới chứa 2 đỉnh nào đó của đồ thị cũ thì sẽ dễ thấy bài này chỉ cần dùng BFS , nhưng mà nếu cài BFS bằng Queue thì có nguy cơ bị TLE.
riêng đoạn code của bạn NKK có thể thay thế đoạn

Code:
until OK or ( mov_no > n*n );
bằng
Code:
 until OK or ( buf_size =0 ) ;
( lúc buf_size==0 thì xem như không thể loang được nữa )
Duy nói rõ về ý tưởng này dckô?

đưa đồ thị ban đầu về đồ thị mới , mỗi đỉnh mới chứa 2 đỉnh bất kỳ của đồ thị cũ , ký hiệu : (u,v) là 1 đỉnh của đồ thị mới với u ,v là 2 đỉnh nào đó của đồ thị ban đầu.
đỉnh (u,v) kề với đỉnh (x,y) khi u kề với x và v kế với y.
Thực hiện BFS từ đỉnh (S,T) cho đến khi tìm ra đỉnh có dạng (x,x) hoặc đã thăm hết tất cả của đỉnh của đồ thị mới
Về Đầu Trang Go down
Sponsored content





bàn về bài QBAGENTS ( đang bị TLE ) Empty
Bài gửiTiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE )   bàn về bài QBAGENTS ( đang bị TLE ) I_icon_minitime

Về Đầu Trang Go down
 
bàn về bài QBAGENTS ( đang bị TLE )
Về Đầu Trang 
Trang 1 trong tổng số 1 trang

Permissions in this forum:Bạn không có quyền trả lời bài viết
BK Algorithm Club :: Giải bài trực tuyến :: SPOJ-
Chuyển đến