Tải bản đầy đủ (.docx) (13 trang)

BTL Toán rời rạc 2 Ptit

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (51.67 KB, 13 trang )

Mơn học: Tốn Rời Rạc 2
Bài 1: Viết hàm DFS
int n,m; bool visit[1000];
int a[1000][1000],ke[1000];
void DFS(int u){
visit[u]=true;
cout<cout<<"("<for(int i=1;i<=n;i++){
if(a[u][i]==1 && visit[i]==false){
ke[i]=u;
DFS(i);
}
}
}
Bài 2: Viết hàm BFS
int n,m; bool visit[1000];
int a[1000][1000],ke[1000];
void BFS(int u){
queue<int> q;
q.push(u);
visit[u]=true;
while(q.size()){
int x=q.front(); q.pop();
cout<for(int i=1;i<=n;i++){
if(a[x][i]==1 && visit[i]==false){
q.push(i);
visit[i]=true;
ke[i]=x;
}


}
}
}
Bài 3: Viết hàm TPLT_DFS tìm số thành phần liên thơng
int n; bool visit[1000];
int a[1000][1000],ke[1000];
void DFS(int u){
visit[u]=true;
for(int i=1;i<=n;i++){
if(a[u][i]==1 && visit[i]==false){
DFS(i);


}
}
}
void TPLT_DFS(int a[1000][1000]){
int so_tplt=0;
memset(visit,false,sizeof(visit));
for(int i=1;i<=n;i++){
if(visit[i]==false){
so_tplt++;
DFS(i);
}
}
cout<}
Bài 4: Viết hàm TPLT_BFS tìm số thành phần liên thông
int n,m; bool visit[1000];
int a[1000][1000],ke[1000];

void BFS(int u){
queue<int> q;
q.push(u); visit[u]=true;
while(q.size()){
int x=q.front(); q.pop();
for(int i=1;i<=n;i++){
if(a[x][i]==1 && visit[i]==false){
q.push(i);
visit[i]=true;
}
}
}
}
void TPLT_BFS(int a[1000][1000]){
int so_tplt=0;
memset(visit,false,sizeof(visit));
for(int i=1;i<=n;i++){
if(visit[i]==false){
so_tplt++;
BFS(i);
}
}
cout<}


Bài 5: Viết hàm T_DFS tìm cây khung của đồ thị
int n,m; bool visit[1000];
int a[1000][1000],ke[1000];
void DFS(int u){

visit[u]=true;
for(int i=1;i<=n;i++){
if(a[u][i]==1 && visit[i]==false){
ke[i]=u;
DFS(i);
}
}
}
void T_DFS(int a[1000][1000]){
memset(visit, false, sizeof(visit));
DFS(1);
int dem=0;
for(int i=1;i<=n;i++) if(visit[i]==true) dem++;
if(dem==n){
for(int i=1;i<=n;i++){
if(ke[i]!=0) cout<<"("<}
}
else cout<<"Khong co cay khung";
}
Bài 6: Viết hàm T_BFS tìm cây khung của đồ thị
int n,m;
int a[1000][1000],ke[1000];
bool visit[1000];
void BFS(int u){
queue<int> q;
q.push(u); visit[u]=true;
while(q.size()){
int x=q.front(); q.pop();
for(int i=1;i<=n;i++){

if(a[x][i]==1 && visit[i]==false){
q.push(i);
ke[i]=x;
visit[i]=true;
}
}
}
}
void T_BFS(int a[1000][1000]){


memset(visit, false, sizeof(visit));
BFS(1);
int dem=0;
for(int i=1;i<=n;i++) if(visit[i]==true) dem++;
if(dem==n){
for(int i=1;i<=n;i++){
if(ke[i]!=0) cout<<"("<}
}
else cout<<"Khong co cay khung";
}
Bài 7: Viết hàm Euler tìm chu trình/ đường đi Euler
int n,vo_huong;
int dinh_bat_dau=0; bool visit[1000];
int a[1000][1000], b[1000][1000], ke[1000];
void DFS(int u){
visit[u]=true;
for(int i=1;i<=n;i++){
if(visit[i]==false) DFS(i);

}
}
int do_thi(){
cin>>n;
do{ //vo_huong=1 là đồ thị vơ hướng,vo_huong=0 là đồ thị có hướng
cin>>vo_huong;
if(vo_huong!=1 && vo_huong!=0) cout<<"Nhap lai"<}
while(vo_huong!=1 && vo_huong!=0);
if(vo_huong==1) cout<<"Do thi vo huong"<else cout<<"Do thi co huong"<return vo_huong;
}
int lien_thong_yeu(){
// kiểm tra tính liên thơng yếu của đồ thị có hướng
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==1){
b[i][j]==1; b[j][i]==1;
}
}
}
DFS(1);
for(int i=1;i<=n;i++){
if(visit[i]==false) return 0;


}
return 1;
}

int kiem_tra_co_huong(){ // return 0 là khơng có, 1 là có chu trình, 2 là có đường đi
if(lien_thong_yeu() == 0) return 0;
int dem = 0;
for(int i=1;i<=n;i++){
int bac_vao=0, bac_ra=0;
for(int j=1;j<=n;j++){
if(a[i][j]==1) bac_ra++;
if(a[j][i]==1) bac_vao++;
}
if(bac_vao!=bac_ra){
// gán dinh_bat_dau là đỉnh có deg+>degdem++;
if(abs(bac_vao-bac_ra)>1) return 0;
if(bac_ra==bac_vao+1) dinh_bat_dau=i;
}
}
if(dem==0) return 1;
if(dem>2) return 0;
else return 2;
}
int kiem_tra_vo_huong(){ // return 0 là khơng có, 1 là có chu trình, 2 là có đường đi
int ok= 1;
DFS(1);
for(int i=1;i<=n;i++) if(visit[i]==false){
return 0;
}
int so_bac_le=0;
for(int i=1;i<=n;i++){
int deg=0;
for(int j=1;j<=n;j++){
if(a[i][j]==1) deg++;

}
if(deg%2==1) so_bac_le++;
if(so_bac_le>2) return 0;
if(dinh_bat_dau==0){
// gán dinh_bat_dau là đỉnh bậc lẻ nhỏ nhất
if(so_bac_le!=0) dinh_bat_dau=i;
}
if(so_bac_le==0) dinh_bat_dau=1;
else ok=2;
}
return ok;
}


void Euler(int a[1000][1000]){
int e[1000], s[1000];
int top=0,k=0;
top++; s[top]=dinh_bat_dau;
while(top>0){
int v=s[top];
int ok=1;
for(int x=1;x<=n;x++){
if(a[v][x]==1){
top++;
s[top]=x; ok=0;
a[v][x]=0;
if(vo_huong==1) a[x][v]=0;
break;
}
}

if(ok==1){
k++; e[k]=v;
top--;
}
}
for(int i=k;i>0;i--) cout<}
void solve(){
do_thi();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) cin>>a[i][j];
}
if(vo_huong==1){
if(kiem_tra_vo_huong()==0){
cout<<"Khong co";
return ;
}
if(kiem_tra_vo_huong()==1){
cout<<"Co chu trinh Euler, bat dau tai dinh 1 "<Euler(a);
}
if(kiem_tra_vo_huong()==2){
cout<<"Co duong di bat dau tu dinh ";
cout<Euler(a);
}
}
else{



if(kiem_tra_co_huong()==0){
cout<<"Khong co";
return ;
}
if(kiem_tra_co_huong()==1){
cout<<"Co chu trinh Euler, bat dau tai dinh 1 "<Euler(a);
}
if(kiem_tra_co_huong()==2){
cout<<"Co duong di bat dau tu dinh ";
cout<cout<Euler(a);
}
}
}
Bài 8: Viết hàm DIJKSTRA tìm đường đi ngắn nhất
int n,s,t, oo=999999;
// oo là vơ cùng, a[i][j]=oo là khơng có đường đi từ i → j
int e[1000],d[1000];
int a[1000][1000];
bool visit[1000];
void ket_qua(){
if(d[t]< oo){
cout<<"Duong di ngan nhat tu dinh "<int i=e[t]; cout<while(i!=s){
cout<}
cout<

}
else cout<<"Khong co duong di";
}
void DIJKSTRA(int s){
for (int v=1;v<=n;v++){
d[v]=a[s][v];
e[v]=s;
visit[v]=false;
}
e[s]=0;
d[s]=0;
visit[s]=true;
while (visit[t]==false){
int u, min= oo;
for (int v=1;v<=n;v++){
if (visit[v]==false && d[v]

u=v;
min=d[v];
}
}
visit[u]=true;
for (int v=1;v<=n;v++){
if (visit[v]==false && d[v]>d[u]+a[u][v]){
d[v]=d[u]+a[u][v];
e[v]=u;
}
}
}

}
void solve(){
cin>>n>>s>>t;
// s là đỉnh bắt đầu, t là đỉnh kết thúc
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
cin>>a[i][j];
if(a[i][j]==0) a[i][j]= oo;
}
memset(visit,false,sizeof(visit));
memset(e,0,sizeof(e)); memset(d,0,sizeof(d));
DIJKSTRA(s);
ket_qua();
}
Bài 9: Viết hàm FLOYD tìm đường đi ngắn nhất
int n, oo=999999;
int a[1000][1000];
int d[1000][1000],e[1000][1000];
void FLOYD(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
d[i][j]=a[i][j];
if(d[i][j]== oo) e[i][j]=0;
e[i][j]=j;
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(d[i][j]>d[i][k]+d[k][j]){

d[i][j]=d[i][k]+d[k][j];
e[i][j]=e[i][k];
}


}
}
}
for(int i=1;i<=n;i++){
// in ra đường đi của từng cặp đỉnh
for(int j=1;j<=n;j++){
if(d[i][j]<0) cout<<"Duong di tu dinh "<am"<else if(i!=j){
cout<<"Duong di tu dinh "<cout<int u=i,v=j;
cout<while(u!=v){
cout<<" -> "<u=e[u][v];
}
cout<}
}
}
}
void solve(){
cin>>n;
memset(d, 0,sizeof(d)); memset(e,0,sizeof(e));

for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
cin>>a[i][j];
if(a[i][j]==0) a[i][j]= oo;
}
FLOYD();
}
Bài 10: Viết hàm PRIM tìm cây khung nhỏ nhất
int n,s, a[1000][1000], oo=999999;
int visit[1000], d[1000], e[1000];
void PRIM(int s){
memset(visit,0,1000);
for (int v=1;v<=n;v++){
d[v]=a[s][v]; e[v]=s;
}
visit[s]=1; d[s]=0; e[s]=0;
int wt=0, dem=1;
while(demint u=0; int min= oo;
for(int v=1;v<=n;v++)


if(visit[v]==0 && d[v]min=d[v]; u=v;
}
dem++;
if(u==0){
cout<<"Khong co cay khung";
return;
}

visit[u]=1;
wt=wt+a[u][e[u]];
for(int v=1;v<=n;v++)
if(visit[v]==0 && d[v]>a[u][v]){
d[v]=a[u][v]; e[v]=u;
}
}
cout<<"Cay khung nho nhat co Wt="<for(int v= 1; v<= n; v++)
if(e[v]!=0) cout<return;
}
void solve(){
cin>>n>>s;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
if(a[i][j]==0) a[i][j]= oo;
}
}
PRIM(s);
}
Bài 11: Viết hàm KRUSKAL tìm cây khung nhỏ nhất
int n, d[1000], c[1000], ts[1000], tg, oo=999999;
int vs[1000], t[1000], a[1000][1000];
void KRUSKAL(int a[1000][1000]) {
int m = 1;
for (int i = 1; i <= n-1; i++) {
for (int j = i+1; j <= n; j++) {
if (a[i][j] != oo && i != j) {

d[m] = i; c[m] = j; ts[m] = a[i][j];
m++;
}
}
}
m--;


for (int i = 1; i <= m-1; i++) {
for (int j = i+1;j <= m; j++ ){
if (ts[i] > ts[j]){
swap(ts[i],ts[j]);
swap(d[i],d[j]);
swap(c[i],c[j]);
}
}
}
int wt = 0, k = 0;
for (int i = 1; i <= n; i++) vs[i]= 0;
for (int i = 1; i<=m; i++) {
if (!(vs[d[i]] != 0 && vs[d[i]] == vs[c[i]])) {
k++; t[k] = i; wt = wt + ts[i];
if (k == n - 1) {
cout << wt << endl;
for (int j = 1; j <= k; j++){
cout << d[t[j]] << " " << c[t[j]] << endl;
}
return;
}
else{

cout<<"Khong co cay khung";
return;
}
int u = d[i], v = c[i];
if (vs[u] == 0 && vs[v] == 0) {
vs[u] = k; vs[v] = k;
}
else if (vs[u] == 0 && vs[v] != 0) vs[u]=vs[v];
else if (vs[u] != 0 && vs[v] == 0) vs[v]=vs[u];
else if (vs[u] < vs[v]) {
tg= vs[v];
for (int j = 1; j <= n; j++) if(vs[j]==tg) vs[j]=vs[u];
}
else if (vs[v] < vs[u]){
tg= vs[u];
for(int j= 1; j<= n; j++) if(vs[j] == tg) vs[j]=vs[v];
}
}
}
}
void solve(){
cin>>n;
for(int i=1; i<=n; i++){


for(int j=1; j<=n; j++){
cin >> a[i][j];
if(a[i][j]==0) a[i][j]= oo;
}
}

KRUSKAL(a);
}
Bài 12: Viết chương trình tìm luồng cực đại
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100;
int n, s = 1, t, g[MAX][MAX], f[MAX][MAX], trace[MAX];
bool BFS(){
queue<int> q;
q.push(s);
memset(trace, 0, sizeof(trace));
trace[s] = -1;
while(!q.empty()){
int u = q.front();
q.pop();
for(int v = 1; v <= n; v++){
if(trace[v] == 0 && g[u][v] > f[u][v]){
trace[v] = u;
if(v == t){
return true;
}
q.push(v);
}
}
}
return false;
}
int Ford_Fulkerson(){
int max_flow = 0;
while(BFS()){

int delta = INT_MAX;
for(int v = t; v != s; v = trace[v]){
int u = trace[v];
delta = min(delta, g[u][v] - f[u][v]);
}
for(int v = t; v != s; v = trace[v]){
int u = trace[v];
f[u][v] += delta;


f[v][u] -= delta;
}
max_flow += delta;
}
return max_flow;
}
void solve(){
ifstream in("DT.INP");
ofstream out("DT.OUT");
in >> n;
t = n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++) in >> g[i][j];
}
int max_flow = Ford_Fulkerson();
out << "Max flow : Val(f) = " << max_flow << endl;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(f[i][j]<0)
f[i][j]=0;

out << f[i][j] << " ";
}
out << endl;
}
in.close();
out.close();
}
main(){
solve();
}



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×