| bàn về bài QBAGENTS ( đang bị TLE ) | |
|
|
Tác giả | Thông điệp |
---|
duy bắt đầu sự nghiệp đi học
Tổng số bài gửi : 11 Join date : 02/12/2008
| Tiêu đề: bàn về bài QBAGENTS ( đang bị TLE ) 31.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++) 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 | |
|
| |
NKK bắt đầu sự nghiệp đi học
Tổng số bài gửi : 13 Join date : 28/12/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 01.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. | |
|
| |
ktuan dzô THCS
Tổng số bài gửi : 30 Join date : 02/01/2009
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 01.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 | |
|
| |
ktuan dzô THCS
Tổng số bài gửi : 30 Join date : 02/01/2009
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 01.02.09 20:00 | |
| addnick: lekhactuanlamson0710 | |
|
| |
duy bắt đầu sự nghiệp đi học
Tổng số bài gửi : 11 Join date : 02/12/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 04.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 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 ) | |
|
| |
NKK bắt đầu sự nghiệp đi học
Tổng số bài gửi : 13 Join date : 28/12/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 04.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 | |
|
| |
lenhhoxung bắt đầu sự nghiệp đi học
Tổng số bài gửi : 29 Join date : 26/11/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 05.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) | |
|
| |
lenhhoxung bắt đầu sự nghiệp đi học
Tổng số bài gửi : 29 Join date : 26/11/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 05.02.09 18:50 | |
| mà mới nghĩ vậy thôi, chưa code, tối về code thừ xem. | |
|
| |
lenhhoxung bắt đầu sự nghiệp đi học
Tổng số bài gửi : 29 Join date : 26/11/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 05.02.09 21:54 | |
| Hình như ý tưởng của mình lởm rùi, sorry vì spam:D | |
|
| |
lenhhoxung bắt đầu sự nghiệp đi học
Tổng số bài gửi : 29 Join date : 26/11/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 05.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
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ô? | |
|
| |
lenhhoxung bắt đầu sự nghiệp đi học
Tổng số bài gửi : 29 Join date : 26/11/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 06.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=20Code 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++]; }
| |
|
| |
duy bắt đầu sự nghiệp đi học
Tổng số bài gửi : 11 Join date : 02/12/2008
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) 06.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
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 | |
|
| |
Sponsored content
| Tiêu đề: Re: bàn về bài QBAGENTS ( đang bị TLE ) | |
| |
|
| |
| bàn về bài QBAGENTS ( đang bị TLE ) | |
|