//蓝桥杯中的状压DP问题,只过了几个测试点,不会做。。。。。。过年了再刷
算法训练 Bus Tour
时间限制:10.0s 内存限制:512.0MB
问题描述
想象你是一个在Warsaw的游客,而且预订了一次乘车旅行,去城镇外看一些令人惊异的景点。这辆公共汽车首先围绕城镇行驶一段时间(一段很长的时间,由于Warsaw是一个大城市),把在各自旅馆的人们带上。接着它就去了那个令人惊异的景点,几个小时后又回到城市中,再一次行驶到每一个旅馆,这一次把乘客放下。
由于某种原因,每当你这样做的时候,你的旅馆总是第一个要上车的,而且是最后一个才下车的,意味着你不得不忍受两段经过所有当地旅馆的不那么愉快的旅行。这很明显不是你想要做的事(除非由于某种原因你真的要进入那些旅馆),所以让我们来做个改变。我们将开发一些软件使得那些观光公司能够把它们的乘车旅行路线安排得更公平——尽管这有时候可能会导致每一个人的总距离更长,但公平就是公平,不是吗?
对于这个问题,有一个起始位置(观光公司的总部),h个需要接送游客的旅馆和一个目的地位置(令人惊异的景点)。我们需要找到一条路径,从总部出发,经过所有的旅馆,到景点去,再回来再一次经过所有的旅馆(可能按照不同的顺序),最后返回总部。为了保证没有一个游客(特别是你)被迫忍受两个完整的旅馆旅行,我们要求在去景点的路上接游客的前个旅馆,在回来的路上也得是前个让游客下车的。受制于这些限制条件,我们想让整个公车旅行尽可能短。注意这些限制条件可能会迫使公共汽车经过某个旅馆但是不停下来(这不算做让游客下车),后来再来这里让游客下车,样例就说明了这种情况。
输入格式
第一行包含两个整数n和m满足3≤n≤20,2≤m,n是位置的总数(旅馆,总部和景点),m是汽车能在两个位置之间行驶的路径条数。
n个不同的位置被标号为0到n-1,0是总部,1到n-2是旅馆,而n-1是景点。假定任意一对位置之间最多只有一条直接路径,而且从任意一个位置都能到达任意另一个位置(并不一定直接到达)。
接下来m行,每行包含三个整数u,v和t,满足0≤u,v≤n-1,u≠v,1≤t≤3600,表示公共汽车可以在t秒的时间内直接在u和v之间到达(两个方向都可以)。
输出格式
一个整数,表示可能的最短路线的总耗时。
样例输入
5 4
0 1 10
1 2 20
2 3 30
3 4 40
样例输出
300
数据规模和约定
对于20%的数据:n=3
对于50%的数据:3≤n≤10
对于100%的数据:3≤n≤20,2≤m
只过了四个测试点:
#include <iostream>
using namespace std;
int main()
{int m,n;
int a[20][20]={0};
int S=0;
int i,u,v;
cin>>n>>m;
for(i=0;i<m;i++)
{cin>>u>>v;
cin>>a[u][v];//表示从u-v的时间
S+=a[u][v];
}
if(n==3) {
//三点三线
if(m==2) {
if(a[0][1]==0){cout<<(2*a[0][2]+4*a[1][2]);return 0;}
if(a[0][2]==0){cout<<2*(a[0][1]+a[1][2]); return 0;}
if(a[1][2]==0){cout<<(2*a[0][2]+4*a[0][1]);return 0;}
}//if m==2
else if(m==3){
if(a[0][1]>(a[0][2]+a[1][2])) {cout<<(2*a[0][2]+4*a[1][2]);return 0;}
else{
cout<<2*(a[0][1]+a[1][2]);return 0;
}
}
}//if n==3
else//n>3
{
if(m==n){//成环
if(a[0][1]>a[0][m-1]) {
if(S>2*(a[0][1]+a[0][m-1])){
cout<<2*(2*(S-a[0][1])-a[0][m-1]);return 0;
}
else if(a[0][1]>a[0][m-1]){
cout<<(S+2*(S-a[0][1]-a[0][m-1])); return 0;
}
else {cout<<(2*S+2*(S-a[0][1]-a[0][m-1]-a[m-2][m-1]));return 0;}
}
}//if m==n
else{
if(a[0][m-1]!=0) {cout<<4*S;return 0;}
else {cout<<(2*(2*S-a[0][1]-a[m-2][m-1]));return 0;}
}//m!=n
}
return 0;
}