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. 可以在两数字间放\(+\)号. 求所有 ...
随机推荐
- BRICH
一.简介 Brich是典型的基于层次的聚类算法.最大的特点就是适合数据量特别大的数据集,处理速度很快,因为该算法扫描一遍数据集. 该算法是利用了一个树状结构来快速聚类,该结构类似平衡B+树.每一个叶子 ...
- SVN管理多个项目版本库 (windows,linux 通用)
SVN管理多个项目版本库: . 安装SVN服务器软件,路径: C:\Program Files\Subversion . 在D盘创建svn根目录D:\SVN-CM . 在D:\SVN-CM下创建SVN ...
- 关于 freetds pymssql 的安装部署
关于 freetds pymssql 的安装部署一.安装: (freetds-0.91 pymssql 2.0.1) 如果要在linux机器 连mysqlsever 1.需要安装freetds./co ...
- PNG24在ie6下的完美解决方法!(DD_belatedPNG)
原网址:http://www.zjgsq.com/1629.html 之前写过一篇<js+css滤镜设置解决PNG24在IE6下显示问题> 解决方法不是很完美,使用起来也比较麻烦. DD_ ...
- JAVA 正则表达式 Regex
//正则表达式,去掉空格.换行.制表位 public static void replaceBlank(){ Pattern p = Pattern.compile("\\s*|\t|\r| ...
- Spring Boot自定义配置与加载
Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...
- PostgreSQL 备份和恢复
备份和恢复有三种不同的基本方法来备份PostgreSQL数据SQL转储文件系统级备份File system level backup连续归档 1. SQL转储 pg_dump dbname > ...
- spring学习十二 application/x-www-form-urlencoded还是application/json
application/x-www-form-urlencoded还是application/json get. POST 用哪种格式? 后台如何得到这些值? 如何用ajax 或者是 postman ...
- [我的CVE][CVE-2017-15709]Apache ActiveMQ Information Leak
问题原因: Apache ActiveMQ默认消息队列61616端口对外,61616端口使用了OpenWire协议,这个端口会暴露服务器相关信息,这些相关信息实际上是debug信息. 会返回应用名称, ...
- 2016.9.9《Oracle查询优化改写技巧与案例》电子工业出版社一书中的技巧
1.coalesce (c1,c2,c3,c4,...) 类似于nvl但可以从多个表达式中返回第一个不是null的值 2.要在where条件中引用列的别名,可以再嵌套一层查询 select * fro ...