程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C說話應用回溯法解觀光售貨員成績與圖的m著色成績

C說話應用回溯法解觀光售貨員成績與圖的m著色成績

編輯:關於C++

C說話應用回溯法解觀光售貨員成績與圖的m著色成績。本站提示廣大學習愛好者:(C說話應用回溯法解觀光售貨員成績與圖的m著色成績)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話應用回溯法解觀光售貨員成績與圖的m著色成績正文


觀光售貨員成績
1.成績描寫:

觀光售貨員成績又稱TSP成績,成績以下:某售貨員要到若干個城市傾銷商品,已知各城市之間的旅程(或盤費盤川),他要選定一條從駐地動身,經由每一個城市一遍最初回到駐地的道路,使總的道路(或總的盤費盤川)最小。數學模子為給定一個無向圖,求遍歷每個極點一次且僅一次的一條回路,最初回到終點的最小消費。

2.輸出請求:

輸出的第一行動測試樣例的個數T( T < 120 ),接上去有T個測試樣例。每一個測試樣例的第一行是無向圖的極點數n、邊數m( n < 12,m < 100 ),接上去m行,每行三個整數u、v和w,表現極點u和v之間有一條權值為w的邊相連。( 1 <= u < v <= n,w <= 1000 )。假定終點(駐地)為1號極點。

3.輸入請求:

對應每一個測試樣例輸入一行,格局為"Case #: W",個中'#'表現第幾個測試樣例(從1開端計),W為TSP成績的最優解,假如找不到可行計劃則輸入-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,      //圖的極點數和邊數
  graph[N][N],   //圖的加權鄰接矩陣
  c=0,       //以後費用
  bestc=-1,     //以後最優值
  x[N],      //以後解
  bestx[N];    //以後最優解
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.輸出請求:
輸出的第一個為測試樣例的個數T ( T < 120 ),接上去有T個測試樣例。每一個測試樣例的第一行是極點數n、邊數M和可用色彩數m( n <= 10,M < 100,m <= 7 ),接上去M行,每行兩個整數u和v,表現極點u和v之間有一條邊相連。( 1 <= u < v <= n )。

3.輸入請求:
對應每一個測試樣例輸入兩行,第一行格局為"Case #: W",個中'#'表現第幾個測試樣例(從1開端計),W為可m著色計劃數。

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;         //輸出測試個數
  while(textNum>0)
  {
    cin>>n;          //輸出極點個數
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    a[i][j]=0;
    cin>>M>>m;         //輸出邊的個數、可用色彩數
    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;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved