一道经典的矩阵题 ( 2010-12-5 16:39)

来源:互联网 发布:java动态添加定时任务 编辑:程序博客网 时间:2024/05/21 09:52

题目:旅行路线选择:设有n 个城市(或景点),今从某市出发遍历各城市,使之旅费最少(即找出
一条旅费最少的路径)。
输入部分:各城市间的旅费。
输出部分:旅费最少的一条路径及总费用。
样例输入:
0 17 13 24 10
10 0 20 9 6
17 29 0 21 28
12 10 22 0 19
12 18 31 20 0
样例输出:
旅途的顺序可以为:1->3->4->2->5->1
总共花费:62元

 

我的代码:

#include<stdio.h> 
#define inf 0x7FFFFFFF
#define N 1001
int a[N][N],b[N][N],c[N][N],d[N];
void huanhuilai(int n){
 int i,j;
 for(i=1;i<=n;i++)
  for(j=1;j<=n;j++)
   c[i][j]=b[i][j];
}
void chushihua(int n)
{
 int i,j,p;
 for(i=1;i<=n;i++)
  for(j=1;j<=n;j++)
   b[i][j]=a[i][j];
 for(i=1;i<=n;i++){
  p=b[i][1];
  for(j=2;j<=n;j++){
   if(b[i][j]<p)
    p=b[i][j]; 
  }
  for(j=1;j<=n;j++){
   if(b[i][j]!=inf)
    b[i][j]-=p;
  }
 }
 for(i=1;i<=n;i++){
  p=b[1][i];
  for(j=2;j<=n;j++){
   if(b[j][i]<p)
    p=b[j][i]; 
  }
  for(j=1;j<=n;j++){
   if(b[j][i]!=inf)
    b[j][i]-=p;
  }
 }
}
void fun(int num,int n)
{
 int p,i,j,min,min2,t,ktv;
 if(num==n)
  return ;
 ktv=inf;  
 for(p=1;p<=n;p++){
  if(p==d[num])
   continue;
  for(i=1;i<=num;i++)
   if(p==d[i]) break;
  if(i<=num)
   continue;
  min2=0;   
  huanhuilai(n); 
  for(i=1;i<=n;i++)
  {
   for(j=1;j<=n;j++){
    if(i==d[num] || j==p)
     c[i][j]=inf; 
   }
  }
   for(i=1;i<=n;i++){
    min=c[i][1];
    for(j=2;j<=n;j++){
     if(c[i][j]<min)
      min=c[i][j]; 
    }//j
    if(min!=inf)
     min2+=min;
    for(j=1;j<=n;j++){
     if(c[i][j]!=inf)
      c[i][j]-=min;
    }//j
   }//i
   for(i=1;i<=n;i++){
    min=c[1][i];
    for(j=2;j<=n;j++){
     if(c[j][i]<min)
      min=c[j][i]; 
    }//j
    if(min!=inf)
     min2+=min;    
    for(j=1;j<=n;j++){
     if(c[j][i]!=inf)
      c[j][i]-=min;
    }//j
   }//i 
   
   
   
   if(min2<ktv){
    ktv=min2;
    t=p;
   }
 }//c
 for(i=1;i<=n;i++)
  for(j=1;j<=n;j++)
   if(i==d[num] || j==t)
    b[i][j]=inf;
 for(i=1;i<=n;i++){
  p=b[i][1];
  for(j=2;j<=n;j++){
   if(b[i][j]<p)
    p=b[i][j]; 
  }
  for(j=1;j<=n;j++){
   if(b[i][j]!=inf)
    b[i][j]-=p;
  }
 }
 for(i=1;i<=n;i++){
  p=b[1][i];
  for(j=2;j<=n;j++){
   if(b[j][i]<p)
    p=b[j][i]; 
  }
  for(j=1;j<=n;j++){
   if(b[j][i]!=inf)
    b[j][i]-=p;
  }
 }     
 d[++num]=t;
 fun(num,n);
}
int main()
{
 int n,m,i,j,sum,num;
 while(scanf("%d",&n)!=EOF){
  if(n==0)
   break;
  for(i=1;i<=n;i++){
   for(j=1;j<=n;j++){
    scanf("%d",&a[i][j]);
    if(a[i][j]==0){
     a[i][j]=inf;
    }
   }
  }
  chushihua(n);
  d[1]=1; 
  sum=0;
  num=1;   
  fun(num,n);
  printf("旅途的顺序可以为:");
  for(i=1;i<=n;i++){
   if(i!=n)
    sum+=a[d[i]][d[i+1]];
   else
    sum+=a[d[i]][d[1]];
  if(i==1) 
   printf("%d",d[i]);
  else if(i==n)
   printf("->%d->%d",d[i],d[1]); 
  else
   printf("->%d",d[i]);   
  }
  printf("\n");
  printf("总共花费:%d元\n",sum);
 }
return 0;
}

//从早上开始了解思想到下午做出来花了很多时间,当然中间看了两集《非诚勿扰》