传送门

题目大意

已知某城市的地铁网由一些地铁线路构成,每一条地铁线路由某一个公司运营,该城市规定:若乘坐同一公司的地铁,从开始到换乘只需要一块钱,换乘其他公司的价格也是一块钱,问从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的更多相关文章

  1. AtCoder ARC061E Snuke's Subway Trip 最短路

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:传送门  Portal  原题目描述在最下面.  \(n(1 ...

  2. Snuke's Subway Trip

    すぬけ君の地下鉄旅行 / Snuke's Subway Trip Time limit : 3sec / Memory limit : 256MB Score : 600 points Problem ...

  3. 【例题收藏】◇例题·I◇ Snuke's Subway Trip

    ◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...

  4. [ARC061E]すぬけ君の地下鉄旅行 / Snuke's Subway Trip

    题目大意:Snuke的城镇有地铁行驶,地铁线路图包括$N$个站点和$M$个地铁线.站点被从$1$到$N$的整数所标记,每条线路被一个公司所拥有,并且每个公司用彼此不同的整数来表示. 第$i$条线路($ ...

  5. AtCoder arc061C Snuke's Subway Trip

    大意: 给你一张无向图,边有种类. 当你第一次/重新进入某种边时费用 + 1 在同一种边之间行走无费用. 求 1 到 n 的最小费用. 嗯...乍一看有一个很直观的想法:记录每个点的最短路的上一条边的 ...

  6. 2018.09.19 atcoder Snuke's Subway Trip(最短路)

    传送门 就是一个另类最短路啊. 利用颜色判断当前节点的最小花费的前驱边中有没有跟当前的边颜色相同的. 如果有这条边费用为0,否则费用为1. 这样跑出来就能ac了. 代码: #include<bi ...

  7. AtCoder 杂题训练

    前言: 因为要普及了,今年没一等就可以退役去学文化课了,所以暑假把历年noip普及组都刷了一遍,离noip还有50+天,想弄点强化训练什么的. 想了想,就这些天学文化课之余有空就把AtCoder之前那 ...

  8. csp退役前的做题计划1(真)

    csp退役前的做题计划1(真) 因为我太菜了,所以在第一次月考就会退役,还是记录一下每天做了什么题目吧. 任务计划 [ ] Z算法(Z Algorithm) 9.28 [x] ARC061C たくさん ...

  9. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

随机推荐

  1. listening 1

    It was regrettable that such great issues had to be the thrust and parry of a general election. But ...

  2. [独孤九剑]Oracle知识点梳理(七)数据库常用对象之Cursor

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  3. 3143 codevs 二叉树的序遍历

    题目描述 Description 求一棵二叉树的前序遍历,中序遍历和后序遍历 输入描述 Input Description 第一行一个整数n,表示这棵树的节点个数. 接下来n行每行2个整数L和R.第i ...

  4. linux下查找命令两则

    由于本人不会阅读man手册,因此需要几下两个常用的查找命令: (1)在某个目录及其子目录查找某个文件并打印完整路径: find ./ -name "assertions.h" -e ...

  5. [转]使用Flexible实现手淘H5页面的终端适配

    曾几何时为了兼容IE低版本浏览器而头痛,以为到Mobile时代可以跟这些麻烦说拜拜.可没想到到了移动时代,为了处理各终端的适配而乱了手脚.对于混迹各社区的偶,时常发现大家拿手机淘宝的H5页面做讨论—— ...

  6. django1.7+nginx1.4.4的static配置

    静态文件指像css,js,images之类的文件. 1.工程配置setting.py STATIC_URL = /static/ STATIC_ROOT = /home/www/winingcpi/s ...

  7. laravel 判断上传文件的类型和后缀

    学习源头: https://blog.csdn.net/ddjjll8877/article/details/52249965 class FileUpdateController extends B ...

  8. FileStream 常用的属性和方法

    FileStream常用的属性和方法 (转) 对流进行操作时要引用 using System.IO; 命名空间 FileStream常用的属性和方法: 属性: CanRead 判断当前流是否支持读取, ...

  9. SQL命令优化

    与数据库交互的基本语言是sql,数据库每次解析和执行sql语句多需要执行很多步骤.以sql server为例,当数据库收到一条查询语句时,语法分析器会扫描sql语句并将其分成逻辑单元(如关键词.表达式 ...

  10. python对MySQL进行数据的插入、更新和删除之后需要commit,数据库才会真的有数据操作。(待日后更新)

    今天在尝试用下面的python代码对MySQL进行数据的插入.更新和删除时, 突然发现代码执行成功, 通过代码查询也显示数据已经插入或更新, 但是当我在MySQL客户端通过SQL语句查询时, 数据库中 ...