Nguồn đề bài: http://vn.spoj.com/problems/LEM3/
1. Đề bài LEM3 spoj
Trong kì nghỉ hè năm nay sherry được bố thưởng cho 1 tour du lịch quanh N đất nước tươi đẹp với nhiều thắng cảnh nổi tiếng ( vì sherry rất ngoan ). Tất nhiên sherry sẽ đi bằng máy bay.
Giá vé máy bay từ đất nước i đến đất nước j là Cij ( dĩ nhiên Cij có thể khác Cji ). Tuy được bố thưởng cho nhiều tiền để đi du lịch nhưng sherry cũng muốn tìm cho mình 1 hành trình với chi phí rẻ nhất có thể để dành tiền mua quà về tặng mọi người ( Các chuyến bay của sherry đều được đảm bảo an toàn tuyệt đối ).
Bạn hãy giúp sherry tìm 1 hành trình đi qua tất cả các nước, mỗi nước đúng 1 lần sao cho chi phí là bé nhất nhé.
Input
Dòng 1: N (5 < N < 16)
Dòng thứ i trong N dòng tiếp theo: Gồm N số nguyên, số thứ j là Cij (0 < Cij < 10001)
Output
Gồm 1 dòng duy nhất ghi chi phí bé nhất tìm được
Example
Input: 6 0 1 2 1 3 4 5 0 3 2 3 4 4 1 0 2 1 2 4 2 5 0 4 3 2 5 3 5 0 2 5 4 3 3 1 0 Output: 8
2. Hướng dẫn LEM3 spoj
Bài này sử dụng BIT và BFS:
Dùng một dãy bit để biểu diễn cách đi của Sherry.
Gọi kc[i][k] là khoảng cách min để sherry đi qua các nước đã được biểu diễn bằng bit 1 trong i và nước cuối cùng đi qua là k.
BFS trên đồ thị có các đỉnh là một cặp số (i,k) (với i, k như trên)
từ một đỉnh (i,k) có thể đi tới đỉnh (i1,k1) với điều kiện:
- Đỉnh k1 được biểu diễn với bit 0 trong i. Khi đó ta có công thức:
kc[i1][k1]=kc[i][k]+c[k][k1];
Mình nói hơi khó hiểu. h mk sẽ share code. Nếu có thắc mắc, các bạn có thể đăng nhập và cmt, mk sẽ giải thích. Cảm ơn! 😀
3. Code mẫu LEM3 spoj
#include <bits/stdc++.h>
#define oo 1000000000;
using namespace std;
typedef pair<int,int> II;
int n,u,v,k,c[17][17],cl[1000000][17],kc[1000000][17];
II q[1000000];
void loang()
{
for(int i=1; i<(1<<n); i++)
for(int j=0; j<=n; j++)
{
kc[i][j]=oo;
cl[i][j]=0;
}
int l=1, r=0;
q[++r]=II(0,0); cl[0][0]=1; kc[0][0]=0;
while(l<=r)
{
II t=q[l++];
u=t.first, k=t.second;
for(int i=1; i<=n; i++)
{
if((u&(1<<(i-1)))==0)
{
v=u|(1<<(i-1));
kc[v][i]=min(kc[v][i],kc[u][k]+c[k][i]);
if(cl[v][i]==0)
{
cl[v][i]=1;
q[++r]=II(v,i);
}
}
}
}
int ds=oo;
for(int i=1; i<=n; i++)
ds=min(ds,kc[(1<<n)-1][i]);
cout<<ds;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
cin>>c[i][j];
loang();
}