Aizu 2200/AOJ2200
2018-03-06 08:54
239 查看
题目大意:快递到了:你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处。而且岛上只有一条船,下次想走水路还是得回到X处才行;两个镇子之间可能有两条以上的水路或旱路;邮递员必须按照清单上的镇子顺序送快递(镇子可能重复,并且对于重复的镇子不允许一次性处理,比如ABCB的话B一定要按顺序走两次才行)。
测试数据有多组:
N M
x1 y1 t1 sl1
x2 y2 t2 sl2
…
xM yM tM slM
R
z1 z2 … zR
N (2 ≤ N ≤ 200) 是镇子的数量,M (1 ≤ M ≤ 10000) 是旱路和水路合计的数量。从第2行到第M + 1行是路径的描述,路径连接xi yi两地,路径花费 ti (1 ≤ ti ≤ 1000)时间,sli 为L时表示是旱路,S时表示是水路。可能有两条及以上路径连接两个镇子,并且路径都是双向的。
M + 2行的R是利腾需要去的镇子的数量,M + 3是利腾需要去的镇子的编号。
初始状态利腾和船都在第一个镇子,且肯定有方法达到需要去的镇子。
测试数据为0 0的时候表示终止。
比较复杂的一个floyd与动态规划的结合…其实认为就是一个动态规划也没问题,毕竟floyd本身也是dp。
Floyd 预处理 水路和陆路的两点最短距离
然后dp[i][j]代表到达了第i个要求达到的小镇tar[i],船停在j镇。
其余见注释。
测试数据有多组:
N M
x1 y1 t1 sl1
x2 y2 t2 sl2
…
xM yM tM slM
R
z1 z2 … zR
N (2 ≤ N ≤ 200) 是镇子的数量,M (1 ≤ M ≤ 10000) 是旱路和水路合计的数量。从第2行到第M + 1行是路径的描述,路径连接xi yi两地,路径花费 ti (1 ≤ ti ≤ 1000)时间,sli 为L时表示是旱路,S时表示是水路。可能有两条及以上路径连接两个镇子,并且路径都是双向的。
M + 2行的R是利腾需要去的镇子的数量,M + 3是利腾需要去的镇子的编号。
初始状态利腾和船都在第一个镇子,且肯定有方法达到需要去的镇子。
测试数据为0 0的时候表示终止。
比较复杂的一个floyd与动态规划的结合…其实认为就是一个动态规划也没问题,毕竟floyd本身也是dp。
Floyd 预处理 水路和陆路的两点最短距离
然后dp[i][j]代表到达了第i个要求达到的小镇tar[i],船停在j镇。
其余见注释。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace std; int land[205][205],sea[205][205],tar[1005],dp[1005][205]; int main() { int n,m,i,j,k,r; while(cin>>n>>m&&(n+m)){ memset(land,0x3f,sizeof(land));memset(sea,0x3f,sizeof(sea));memset(dp,0x3f,sizeof(dp)); for(i=1;i<=m;i++){ int a,b,c;string str; cin>>a>>b>>c>>str; if(str=="S") sea[a][b]=sea[b][a]=c; else land[a][b]=land[b][a]=c; } for(i=1;i<=n;i++)land[i][i]=sea[i][i]=0;//不要忘了这个.. cin>>r;for(i=1;i<=r;i++)cin>>tar[i]; for(k=1;k<=n;k++)//floyd初始化,至于那些不可能的,初始化完了肯定还是无穷大不可能 for(i=1;i<=n;i++) for(j=1;j<=n;j++){ land[i][j]=min(land[i][j],land[i][k]+land[k][j]); sea[i][j]=min(sea[i][j],sea[i][k]+sea[k][j]); } dp[1][tar[1]]=0;//初始化 for(i=1;i<=r;i++)//从2开始也没问题 for(j=1;j<=n;j++){ dp[i][j]=min(dp[i][j],dp[i-1][j]+land[tar[i-1]][tar[i]]);//单纯走陆路的情况,从tar[i-1]到tar[i] for(k=1;k<=n;k++){//回到船停的j镇,水路从j到k,陆路k到tar[i],枚举k dp[i][k]=min((long long)dp[i][k],(long long)dp[i-1][j]+land[tar[i-1]][j]+sea[j][k]+land[k][tar[i]]); //注意这里一定是dp[i][k]而不是dp[i][j] } } int ans=0x7f7f7f7f; for(i=1;i<=n;i++) ans=min(ans,dp[r][i]); cout<<ans<<endl; } return 0; }
相关文章推荐
- Aizu-2200-floyd+dp
- Aizu-2200 Mr. Rito Post Office
- Aizu:2200-Mr. Rito Post Office
- Aizu 2200 Mr. Rito Post Office【特复杂的floyd+dp】
- EasyARM2200
- SmartARM2200开发板GPIO驱动学习心得
- Aizu 1180 Recurring Decimals
- Aizu 解题报告索引
- AIZU 0005
- 杭电 2200 Eddy's AC难题(排列组合)
- hdu-2200-Eddy's AC难题
- HDU 2200 Eddy's AC难题 -数论
- Aizu - 2555 Everlasting Zero 模拟
- Aizu 2305 Beautiful Currency DP
- Aizu 2170 Marked Ancestor(并查集变形)
- 【Aizu 2305】Beautiful Currency
- Aizu 2224 Save your cats【最大生成树】
- Aizu 2224 (并查集 Save you cat )
- Aizu 0005 GCD and LCM(欧几里得)
- 【哈理工OJ 750题纪念!】Hrbust 2200 Escaping【建图+最大流-------Dinic】