1150 Travelling Salesman Problem (25分)
判断是否访问所有结点,并回到出发结点。
并找到所有符合要求的给定方案中(访问所有结点并成环)的最短路径。
#include<iostream> //输入输出流头文件
#include<vector> //变长数组容器
using namespace std; //标准命名空间
int n,m;
int a[201][201]={0};//可以加入全局变量或者其他函数
int checkTS(vector<int> v);
int main(){ //主函数
#ifdef ONLINE_JUDGE //如果有oj系统(在线判定),则忽略文件读入,否则使用文件作为标准输入
#else
freopen("1.txt", "r", stdin); //从1.txt输入数据
#endif
cin>>n>>m;
for(int i=0;i<m;i++){
int x,y,d;
cin>>x>>y>>d;
a[x][y]=a[y][x]=d;
}
int k,kn,dist,mindist=2147483647,mindistloc;
cin>>k;
for(int i=1;i<=k;i++){
cin>>kn;
vector<int> v(kn);
for(int j=0;j<kn;j++){
cin>>v[j];
}
cout<<"Path "<<i<<": ";
dist=checkTS(v);
if(dist>0&&mindist>dist){
mindist=dist;
mindistloc=i;
}
}
cout<<"Shortest Dist("<<mindistloc<<") = "<<mindist<<endl;
return 0; //返回0,如果不返回0,PAT会报错
}
int checkTS(vector<int> v){
int dis=0,simple=0;
int *flag=new int[n+1];
fill(flag,flag+n+1,0);
for(int i=0;i<v.size()-1;i++){
if(a[v[i]][v[i+1]]){
dis+=a[v[i]][v[i+1]];
}
else {dis=-1;break;}
if(flag[v[i]]==1){simple=1;}//不是一个简单的环
flag[v[i]]=1;
}
if(dis>0)cout<<dis<<" (";
else cout<<"NA (";
if(v.size()<n+1||v[0]!=v[v.size()-1]||dis<0){//v中的数据少于n+1个不能形成环||头尾不衔接||存在不直接相连的点
cout<<"Not a TS cycle)"<<endl;
return -1;
}
for(int i=1;i<=n;i++){
if(flag[i]==0) {//没有包含所有点
cout<<"Not a TS cycle)"<<endl;
return -1;
}
}
if(simple) cout<<"TS cycle)"<<endl;
else cout<<"TS simple cycle)"<<endl;
return dis;
}