题意:
你是某个岛国(ACM-ICPC Japan )上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处。而且岛上只有一条船,下次想走水路还是得回到X处才行;两个镇子之间可能有两条以上的水路或旱路;邮递员必须按照清单上的镇子顺序送快递(镇子可能重复,并且对于重复的镇子不允许一次性处理,比如ABCB的话B —定要按顺序走两次才行)。
测试数据有多组:
N M
xl yl tl sll
x2 y2 t2 sl2
XM yM tM SIM
R
Zl Z2 ... ZR
N (2 <= N <= 200)是镇子的数星,M (1 <= M <= 10000)是旱路和水路合计的数量。
从第2行到第M+1行是路径的描述,路径连接xi yi两地,路径花费ti (1 s ti s 1000)时间,sli为L时表示是旱路,S时表示是水路。
可能有两条及以上路径连接两个镇子,并且路径都是双向的。
M + 2行的R是利腾需要去的镇子的数量,M + 3是利腾需要去的镇子的编号
初始状态利腾和船都在第一个镇子,且肯定有方法达到需要去的镇子。
测试数据为0 0的时候表示终止。
样例输入
3 3 1 2 5 L 1 2 7 S 2 3 11 S 3 1 2 3 5 5 1 2 15 L 2 3 10 L 4 5 7 L 1 3 30 S 3 4 100 S 5 1 3 5 4 1 0 0
样例输出
18
269
分析
这道dp题还是比较容易想的,不过有一个坑人的地方!
因为要转移的参考量,一是当前位置,二是船的位置,那么设dp[i][j]为走到第i个城市,船停在j
那么状态转移方程就是dp[i][j]=min(dp[i-1][k]+l[id[i-1]][k]+s[k][j]+l[j][id[i]],dp[i][j]);
但是j==k的时候,不要去移船!dp[i][j]=min(dp[i-1][k]+l[id[i-1][id[i]],dp[i][j]);
代码
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<cmath> 6 #include<cstdio> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 #define RG register ll 11 #define rep(i,a,b) for(RG i=a;i<=b;++i) 12 #define per(i,a,b) for(RG i=a;i>=b;--i) 13 #define ll long long 14 #define inf (1<<29) 15 #define maxn 205 16 #define maxr 1005 17 using namespace std; 18 ll n,m,cnt; 19 ll l[maxn][maxn],s[maxn][maxn],id[maxr],dp[maxr][maxn]; 20 inline ll read() 21 { 22 ll x=0,f=1;char c=getchar(); 23 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 24 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 25 return x*f; 26 } 27 28 void DP() 29 { 30 memset(dp,63,sizeof(dp)); 31 dp[1][id[1]]=0; 32 rep(i,2,cnt) 33 rep(j,1,n) 34 rep(k,1,n) 35 { 36 if(j!=k) // 37 dp[i][j]=min(dp[i-1][k]+l[id[i-1]][k]+s[k][j]+l[j][id[i]],dp[i][j]); 38 else 39 dp[i][j]=min(dp[i-1][k]+l[id[i-1]][id[i]],dp[i][j]); 40 } 41 ll mn=inf; 42 rep(i,1,n) mn=min(mn,dp[cnt][i]); 43 cout<<mn<<endl; 44 } 45 46 int main() 47 { 48 char opt; 49 while(1) 50 { 51 n=read(),m=read(); 52 if(!n) return 0; 53 rep(i,1,n)rep(j,1,n) l[i][j]=s[i][j]=inf; 54 rep(i,1,n) l[i][i]=s[i][i]=0; 55 for(RG i=1,a,b,c;i<=m;i++) 56 { 57 a=read(),b=read(),c=read();opt=getchar(); 58 if(opt=='L') l[a][b]=l[b][a]=c; 59 else s[a][b]=s[b][a]=c; 60 } 61 rep(k,1,n)rep(i,1,n)rep(j,1,n) l[i][j]=min(l[i][j],l[i][k]+l[k][j]),s[i][j]=min(s[i][j],s[i][k]+s[k][j]); 62 cnt=read(); 63 rep(i,1,cnt) id[i]=read(); 64 DP(); 65 } 66 return 0; 67 }