ARC061E Snuke's Subway Trip
题目大意
已知某城市的地铁网由一些地铁线路构成,每一条地铁线路由某一个公司运营,该城市规定:若乘坐同一公司的地铁,从开始到换乘只需要一块钱,换乘其他公司的价格也是一块钱,问从1号地铁站到n号地铁站的最低价格。
分析
做法1:
这个题在原图上跑显然是不可能的,所以我们需要考虑如何重新构图,首先我们想到如果数个点能被一条线连接就可以不花钱,所以我们可以考虑把他们缩成一点,我们有不难想到如果有两条线路是一家公司的但是它们不相连则它们和由不同两个公司运营效果是一样的。于是我们便得到了构图思路:枚举每一家公司,将一家公司中所有能相连的点连到一个新点上,对于每家公司可能会产生多个新点,这就是我们之前说的不相连的由同一公司运营的点相当于由两个不同公司运行的,我们有了新点后将原来点与它现在所属的“新公司”相连,这样就构成了一个二分图,将每条边的权值赋为1,bfs求最短路最终答案除以2就行了。
做法2:
我们不再考虑缩点而考虑拆点,将每一个站点按连接它的铁路的所属公司拆违k个不同点,然后再额外创建一个0点,每一次换公司都要先走到这个0点再转换到其它公司。注意代码中的p.p表示当前车站,p.b表示所属公司。p.c为到达此站的最小花费,具体实现见代码。
代码
//做法1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl;
struct node {
int x,y,c;
}e[];
int id[],fa[],n,m,newn,d[],used[];
vector<int>v[];
inline bool cmp(const node a,const node b){
return a.c<b.c;
}
inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
inline void deal(int le,int ri){
int i;
for(i=le;i<=ri;i++){
fa[e[i].x]=e[i].x;
fa[e[i].y]=e[i].y;
used[e[i].x]=used[e[i].y]=;
id[e[i].x]=id[e[i].y]=-;
}
for(i=le;i<=ri;i++)
if(sf(e[i].x)!=sf(e[i].y)){
fa[sf(e[i].x)]=sf(e[i].y);
}
for(i=le;i<=ri;i++){
int xx=sf(e[i].x),yy=sf(e[i].y);
if(!used[e[i].x]){
if(id[xx]==-)id[xx]=++newn;
v[e[i].x].push_back(id[xx]);
v[id[xx]].push_back(e[i].x);
used[e[i].x]=;
}
if(!used[e[i].y]){
if(id[yy]==-)id[yy]=++newn;
v[e[i].y].push_back(id[yy]);
v[id[yy]].push_back(e[i].y);
used[e[i].y]=;
}
}
}
queue<int>q;
int main(){
int i,l=;
scanf("%d%d",&n,&m);
newn=n;
for(i=;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].c);
sort(e+,e+m+,cmp);
for(i=;i<=m;i++)
if(e[i].c!=e[i-].c){
deal(l,i-);
l=i;
}
deal(l,m);
memset(d,-,sizeof(d));
d[]=;
q.push();
while(!q.empty()){
int x=q.front();
q.pop();
for(i=;i<(int)v[x].size();i++)
if(d[v[x][i]]==-){
d[v[x][i]]=d[x]+;
q.push(v[x][i]);
}
}
if(d[n]==-)puts("-1");
else cout<<d[n]/<<endl;
return ;
}
//做法2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl;
#define foreach(i,dat) for(__typeof(dat.begin()) i = dat.begin();i!=dat.end();++i)
const int inf=1e9+7;
struct node {
int p,b,c;
};
inline bool operator < (node x,node y){return x.c>y.c;}
map<int,vector<int> >e[100100];
vector<int>v[100100];
map<int,int>d[100100];
priority_queue<node>q;
int main(){
int n,m,i,x,y,z;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
x--,y--;
e[x][z].push_back(y);
e[y][z].push_back(x);
v[x].push_back(z);
v[y].push_back(z);
}
q.push({0,0,0});;
d[0][0]=0;
while(!q.empty()){
node p=q.top();
q.pop();
if(d[p.p][p.b]!=p.c)continue;
if(d[p.p].find(0)==d[p.p].end()||d[p.p][0]>p.c){
d[p.p][0]=p.c;
q.push({p.p,0,p.c});
}
if(!p.b){
for(i=0;i<(int)v[p.p].size();i++)
if(d[p.p].find(v[p.p][i])==d[p.p].end()||d[p.p][v[p.p][i]]>p.c+1){
d[p.p][v[p.p][i]]=p.c+1;
q.push({p.p,v[p.p][i],p.c+1});
}
continue;
}
for(i=0;i<(int)e[p.p][p.b].size();i++)
if(d[e[p.p][p.b][i]].find(p.b)==d[e[p.p][p.b][i]].end()
||d[e[p.p][p.b][i]][p.b]>p.c){
d[e[p.p][p.b][i]][p.b]=p.c;
q.push({e[p.p][p.b][i],p.b,p.c});
}
}
int ans=inf;
for(map<int,int>::iterator it=d[n-1].begin();it!=d[n-1].end();it++)
ans=min(ans,it->second);
if(ans==inf)puts("-1");
else printf("%d\n",ans);
return 0;
}
ARC061E Snuke's Subway Trip的更多相关文章
- AtCoder ARC061E Snuke's Subway Trip 最短路
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:传送门 Portal 原题目描述在最下面. \(n(1 ...
- Snuke's Subway Trip
すぬけ君の地下鉄旅行 / Snuke's Subway Trip Time limit : 3sec / Memory limit : 256MB Score : 600 points Problem ...
- 【例题收藏】◇例题·I◇ Snuke's Subway Trip
◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...
- [ARC061E]すぬけ君の地下鉄旅行 / Snuke's Subway Trip
题目大意:Snuke的城镇有地铁行驶,地铁线路图包括$N$个站点和$M$个地铁线.站点被从$1$到$N$的整数所标记,每条线路被一个公司所拥有,并且每个公司用彼此不同的整数来表示. 第$i$条线路($ ...
- AtCoder arc061C Snuke's Subway Trip
大意: 给你一张无向图,边有种类. 当你第一次/重新进入某种边时费用 + 1 在同一种边之间行走无费用. 求 1 到 n 的最小费用. 嗯...乍一看有一个很直观的想法:记录每个点的最短路的上一条边的 ...
- 2018.09.19 atcoder Snuke's Subway Trip(最短路)
传送门 就是一个另类最短路啊. 利用颜色判断当前节点的最小花费的前驱边中有没有跟当前的边颜色相同的. 如果有这条边费用为0,否则费用为1. 这样跑出来就能ac了. 代码: #include<bi ...
- AtCoder 杂题训练
前言: 因为要普及了,今年没一等就可以退役去学文化课了,所以暑假把历年noip普及组都刷了一遍,离noip还有50+天,想弄点强化训练什么的. 想了想,就这些天学文化课之余有空就把AtCoder之前那 ...
- csp退役前的做题计划1(真)
csp退役前的做题计划1(真) 因为我太菜了,所以在第一次月考就会退役,还是记录一下每天做了什么题目吧. 任务计划 [ ] Z算法(Z Algorithm) 9.28 [x] ARC061C たくさん ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
随机推荐
- java 网页 保存上传文件
网页请求提交到另外一个jsp 进行处理 index.jsp <%@ page language="java" import="java.util.*" p ...
- UVA - 11754 Code Feat (分块+中国剩余定理)
对于一个正整数N,给出C组限制条件,每组限制条件为N%X[i]∈{Y1,Y2,Y3,...,Yk[i]},求满足条件的前S小的N. 这道题很容易想到用中国剩余定理,然后用求第k小集合的方法输出答案.但 ...
- 性能测试工具BenchmarkDotnet
.NET Core中的性能测试工具BenchmarkDotnet https://www.cnblogs.com/lwqlun/p/9671611.html 背景介绍 之前一篇博客中,我们讲解.NET ...
- net Core 2.1新功能Generic Host(通用主机)
net Core 2.1新功能Generic Host(通用主机) http://doc.okbase.net/CoderAyu/archive/301859.html 什么是Generic Host ...
- How To Uninstall Software Using The Ubuntu Command Line
How To Uninstall Software Using The Ubuntu Command Line Uninstall Ubuntu Software Using The Terminal ...
- shell while的用法
1. #!/bin/shint=1while (( "$int < 10" ))doecho "$int"let "int++"don ...
- BZOJ4154:[IPSC2015]Generating Synergy
浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...
- JDBC小常识
1 JDBC连接数据库6步 Load the JDBC Driver Establish the Database Connection Create a Statement Object Execu ...
- python3小例子:scrapy+mysql
https://blog.csdn.net/u010151698/article/details/79371234
- java代码排序问题
总结: package com.ja; import java.util.Arrays; import java.util.Collections; public class mili { publi ...