maxmin
1150 Travelling Salesman Problem (25 分)
题意
给出一张无向图,和k条路径,判断哪些路径是简单环路,不简单环路,非环路,非连通路。并找出环路中花费最小的路。
1.简单环路:除了起点其他点都经过一次,并从起点开始最后回到起点。
2.非简单环路:从起点开始,最后回到起点,每个点至少经过一次。
3.非环路:没有经过所有点或者起点和终点不同。(并不是没有环)
4.非连通:路径不连通。
思路
遍历每条路,当有不连通路直接就是4,有点没经过或者起点终点不相同就是3,剩下,路径中只有节点数+1的个节点的路即为1,最后剩下的剩下的为2。
在环路中找到最小花费即可。
注意找最小花费时初始化大一点(>1e5),最后一个测试点卡。
代码
#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
int mp[507][507];
int main()
{
int n,m,a,b,c,k,x,y[507],last,vis[507],sum,flog=0,xmin=100000,xxx;//xmin初值>=1e5
vector<int>s;
memset(mp,0,sizeof(mp));
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
mp[a][b]=c;
mp[b][a]=c;
}
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d",&x);
flog=0;
sum=0;
memset(vis,0,sizeof(vis));
for(int j=0;j<x;j++){
scanf("%d",&y[j]);
if(j!=0){
// printf("#\n");
if(flog!=1&&mp[last][y[j]]!=0){
sum+=mp[last][y[j]];
vis[y[j]]=1;
last=y[j];
}else{
flog=1;
}
}else{
last=y[j];
vis[y[j]]=1;
}
}
if(flog==1){
printf("Path %d: NA (Not a TS cycle)\n",i+1);
}else{
for(int j=1;j<=n;j++){
if(vis[j]!=1){
flog=1;
break;
}
}
if(flog==1||y[0]!=y[x-1]){
printf("Path %d: %d (Not a TS cycle)\n",i+1,sum);
}else if(x==n+1){
printf("Path %d: %d (TS simple cycle)\n",i+1,sum);
if(xmin>sum){
xmin=sum;
xxx=i+1;
}
}else{
printf("Path %d: %d (TS cycle)\n",i+1,sum);
if(xmin>sum){
xmin=sum;
xxx=i+1;
}
}
}
}
printf("Shortest Dist(%d) = %d\n",xxx,xmin);
return 0;
}