C語言使用回溯法解旅行售貨員問題與圖的m著色問題
旅行售貨員問題
1.問題描述:
旅行售貨員問題又稱TSP問題,問題如下:某售貨員要到若干個城市推銷商品,已知各城市之間的路程(或旅費),他要選定一條從駐地出發(fā),經(jīng)過每個城市一遍最后回到駐地的路線,使總的路線(或總的旅費)最小。數(shù)學模型為給定一個無向圖,求遍歷每一個頂點一次且僅一次的一條回路,最后回到起點的最小花費。
2.輸入要求:
輸入的第一行為測試樣例的個數(shù)T( T < 120 ),接下來有T個測試樣例。每個測試樣例的第一行是無向圖的頂點數(shù)n、邊數(shù)m( n < 12,m < 100 ),接下來m行,每行三個整數(shù)u、v和w,表示頂點u和v之間有一條權(quán)值為w的邊相連。( 1 <= u < v <= n,w <= 1000 )。假設(shè)起點(駐地)為1號頂點。
3.輸出要求:
對應(yīng)每個測試樣例輸出一行,格式為"Case #: W",其中'#'表示第幾個測試樣例(從1開始計),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,      //圖的頂點數(shù)和邊數(shù)
  graph[N][N],   //圖的加權(quán)鄰接矩陣
  c=0,       //當前費用
  bestc=-1,     //當前最優(yōu)值
  x[N],      //當前解
  bestx[N];    //當前最優(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的各頂點著色,每個頂點著一種顏色。是否有一種著色法使G中每條邊的2個頂點著不同顏色,求有多少種方法為圖可m著色。
2.輸入要求:
輸入的第一個為測試樣例的個數(shù)T ( T < 120 ),接下來有T個測試樣例。每個測試樣例的第一行是頂點數(shù)n、邊數(shù)M和可用顏色數(shù)m( n <= 10,M < 100,m <= 7 ),接下來M行,每行兩個整數(shù)u和v,表示頂點u和v之間有一條邊相連。( 1 <= u < v <= n )。
3.輸出要求:
對應(yīng)每個測試樣例輸出兩行,第一行格式為"Case #: W",其中'#'表示第幾個測試樣例(從1開始計),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;         //輸入測試個數(shù)
  while(textNum>0)
  {
    cin>>n;          //輸入頂點個數(shù)
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    a[i][j]=0;
    cin>>M>>m;         //輸入邊的個數(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;
}
上一篇:解析C++中的虛擬函數(shù)及其靜態(tài)類型和動態(tài)類型
欄 目:C語言
下一篇:大數(shù)據(jù)情況下桶排序算法的運用與C++代碼實現(xiàn)示例
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2202.html
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
 - 04-02c語言的正則匹配函數(shù) c語言正則表達式函數(shù)庫
 - 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
 - 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對數(shù)怎么表達
 - 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
 - 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
 - 04-02c語言沒有round函數(shù) round c語言
 - 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
 - 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
 - 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘
 


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
 - 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
 - 04-02c語言的正則匹配函數(shù) c語言正則表達
 - 04-02c語言用函數(shù)寫分段 用c語言表示分段
 - 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
 - 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
 - 04-02c語言沒有round函數(shù) round c語言
 - 04-02c語言分段函數(shù)怎么求 用c語言求分段
 - 04-02C語言中怎么打出三角函數(shù) c語言中怎
 - 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
 
隨機閱讀
- 08-05DEDE織夢data目錄下的sessions文件夾有什
 - 01-11ajax實現(xiàn)頁面的局部加載
 - 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
 - 01-10delphi制作wav文件的方法
 - 01-10使用C語言求解撲克牌的順子及n個骰子
 - 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
 - 08-05織夢dedecms什么時候用欄目交叉功能?
 - 01-10C#中split用法實例總結(jié)
 - 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
 - 04-02jquery與jsp,用jquery
 


