C語言使用回溯法解旅行售貨員問題與圖的m著色問題
旅行售貨員問題
1.問題描述:
旅行售貨員問題又稱TSP問題,問題如下:某售貨員要到若干個(gè)城市推銷商品,已知各城市之間的路程(或旅費(fèi)),他要選定一條從駐地出發(fā),經(jīng)過每個(gè)城市一遍最后回到駐地的路線,使總的路線(或總的旅費(fèi))最小。數(shù)學(xué)模型為給定一個(gè)無向圖,求遍歷每一個(gè)頂點(diǎn)一次且僅一次的一條回路,最后回到起點(diǎn)的最小花費(fèi)。
2.輸入要求:
輸入的第一行為測試樣例的個(gè)數(shù)T( T < 120 ),接下來有T個(gè)測試樣例。每個(gè)測試樣例的第一行是無向圖的頂點(diǎn)數(shù)n、邊數(shù)m( n < 12,m < 100 ),接下來m行,每行三個(gè)整數(shù)u、v和w,表示頂點(diǎn)u和v之間有一條權(quán)值為w的邊相連。( 1 <= u < v <= n,w <= 1000 )。假設(shè)起點(diǎn)(駐地)為1號頂點(diǎn)。
3.輸出要求:
對應(yīng)每個(gè)測試樣例輸出一行,格式為"Case #: W",其中'#'表示第幾個(gè)測試樣例(從1開始計(jì)),W為TSP問題的最優(yōu)解,如果找不到可行方案則輸出-1。
4.樣例輸入:
2 5 8 1 2 5 1 4 7 1 5 9 2 3 10 2 4 3 2 5 6 3 4 8 4 5 4 3 1 1 2 10
5.樣例輸出:
Case 1: 36 Case 2: -1
6.解決方法:
//旅行售貨員問題 (回溯)
#include<iostream>
#define N 100
using namespace std;
int n,m,w, //圖的頂點(diǎn)數(shù)和邊數(shù)
graph[N][N], //圖的加權(quán)鄰接矩陣
c=0, //當(dāng)前費(fèi)用
bestc=-1, //當(dāng)前最優(yōu)值
x[N], //當(dāng)前解
bestx[N]; //當(dāng)前最優(yōu)解
void backtrack(int k);
void swap(int &a,int &b);
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void backtrack(int k)
{
if(k==n)
{
if( (c+graph[x[n-1]][x[n]]+graph[x[n]][1]<bestc||bestc==-1) && graph[x[n-1]][x[n]]!=-1 && graph[x[n]][1]!=-1 )
{
bestc=c+graph[x[n-1]][x[n]]+graph[x[n]][1];
for(int i=1;i<=n;i++)
{
bestx[i]=x[i];
}
}
return ;
}
else
{
for(int i=k;i<=n;i++)
{
if( graph[x[k-1]][x[i]]!=-1 && (c+graph[x[k-1]][x[i]]<bestc || bestc==-1))
{
swap(x[i],x[k]);
c+=graph[x[k-1]][x[k]];
backtrack(k+1);
c-=graph[x[k-1]][x[k]];
swap(x[i],x[k]);
}
}
}
}
int main(void)
{
int i,j,tmp=1,testNum;
cin>>testNum;
while(tmp<=testNum)
{
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
graph[i][j]=-1;
for(int k=1;k<=m;k++)
{
cin>>i>>j>>w;
graph[i][j]=w;
graph[j][i]=w;
}
for(i=1;i<=n;i++)
{
x[i]=i;
bestx[i]=i;
}
backtrack(2);
cout<<"Case "<<tmp<<": "<<bestc<<endl;
bestc=-1;
c=0;
tmp++;
}
return 0;
}
圖的m著色問題
1.問題描述
給定無向連通圖G和m種不同的顏色。用這些顏色為圖G的各頂點(diǎn)著色,每個(gè)頂點(diǎn)著一種顏色。是否有一種著色法使G中每條邊的2個(gè)頂點(diǎn)著不同顏色,求有多少種方法為圖可m著色。
2.輸入要求:
輸入的第一個(gè)為測試樣例的個(gè)數(shù)T ( T < 120 ),接下來有T個(gè)測試樣例。每個(gè)測試樣例的第一行是頂點(diǎn)數(shù)n、邊數(shù)M和可用顏色數(shù)m( n <= 10,M < 100,m <= 7 ),接下來M行,每行兩個(gè)整數(shù)u和v,表示頂點(diǎn)u和v之間有一條邊相連。( 1 <= u < v <= n )。
3.輸出要求:
對應(yīng)每個(gè)測試樣例輸出兩行,第一行格式為"Case #: W",其中'#'表示第幾個(gè)測試樣例(從1開始計(jì)),W為可m著色方案數(shù)。
4.樣例輸入:
1 5 8 5 1 2 1 3 1 4 2 3 2 4 2 5 3 4 4 5
5.樣例輸出:
Case 1: 360
6.解決方法:
#include<iostream>
using namespace std;
#define N 100
int m,n,M,a[N][N],x[N],textNum;
int static sum=0;
bool ok(int k)
{
for(int j=1;j<=n;j++)
if(a[k][j]&&(x[j]==x[k]))
return false;
return true;
}
void backtrack(int t)
{
if(t>n)
{
sum++;
// for(int i=1;i<=n;i++)
//cout<<x[i]<<" ";
//cout<<endl;
}
else
for(int i=1;i<=m;i++)
{
x[t]=i;
if(ok(t))
backtrack(t+1);
x[t]=0;
}
}
int main()
{
int i,j,z=1;
cin>>textNum; //輸入測試個(gè)數(shù)
while(textNum>0)
{
cin>>n; //輸入頂點(diǎn)個(gè)數(shù)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=0;
cin>>M>>m; //輸入邊的個(gè)數(shù)、可用顏色數(shù)
for(int k=1;k<=M;k++) //生成圖的鄰接矩陣
{
cin>>i>>j;
a[i][j]=1;
a[j][i]=1;
}
/* for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;}*/
for(i=0;i<=n;i++)
x[i]=0;
backtrack(1);
cout<<"Case "<<z<<": "<<sum<<endl;
sum=0;
textNum--;
z++;
}
return 0;
}
相關(guān)文章
QT已有項(xiàng)目導(dǎo)入工程時(shí)注意事項(xiàng)圖文詳解
QT開發(fā)這幾年大大小小項(xiàng)目做了不少,花了點(diǎn)時(shí)間對知識點(diǎn)總結(jié)整合了一部分,下面這篇文章主要給大家介紹了關(guān)于QT已有項(xiàng)目導(dǎo)入工程時(shí)注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2023-11-11
解析Linux內(nèi)核的基本的模塊管理與時(shí)間管理操作
這篇文章主要介紹了Linux內(nèi)核的基本的模塊管理與時(shí)間管理操作,包括模塊加載卸載函數(shù)的使用和定時(shí)器的用法等知識,需要的朋友可以參考下2016-02-02
基于Qt實(shí)現(xiàn)的自定義樹結(jié)構(gòu)容器
在Qt框架中,盡管其提供了許多強(qiáng)大的容器類,但缺少一個(gè)通用的、靈活的樹結(jié)構(gòu)容器,所以本文將設(shè)計(jì)并實(shí)現(xiàn)一個(gè)可復(fù)用的自定義樹結(jié)構(gòu)容器,需要的可以參考下2024-12-12
Matlab實(shí)現(xiàn)繪制高階版本韋恩圖(upset圖)
韋恩圖隨著階數(shù)升高會(huì)越來越復(fù)雜,當(dāng)階數(shù)達(dá)到7或者以上時(shí)幾乎沒辦法繪制,但是使用upset圖卻可以比較輕易的繪制。本文就來用Matlab實(shí)現(xiàn)繪制upset圖,需要的可以參考一下2023-01-01
關(guān)于C++中sort()函數(shù)的用法,你搞明白了沒
這篇文章主要介紹了關(guān)于C++中sort()函數(shù)的用法,并通過三種方法介紹了按降序排列的實(shí)現(xiàn)代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
基于C語言實(shí)現(xiàn)的aes256加密算法示例
這篇文章主要介紹了基于C語言實(shí)現(xiàn)的aes256加密算法,結(jié)合具體實(shí)例形式詳細(xì)分析了C語言實(shí)現(xiàn)的aes256加密算法實(shí)現(xiàn)步驟與使用技巧,需要的朋友可以參考下2017-02-02

