传送门

题目大意

已知某城市的地铁网由一些地铁线路构成,每一条地铁线路由某一个公司运营,该城市规定:若乘坐同一公司的地铁,从开始到换乘只需要一块钱,换乘其他公司的价格也是一块钱,问从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. List集合添加自定义对象

    public class Student { private String name; private int age; public Student() { super(); } public St ...

  2. canvas基础学习(一)

    一.概述 canvas它和其它的HTML5标签的使用基本一致,但是它相当于在浏览器中建立一个画布,可以再这个画布上画图.创建动画甚至是3D游戏.由于canvas要适配不同终端的分辨率,所以尽可能的在标 ...

  3. Python中类的约束

    如何在python中进行类的约束 使某些类必须有一些方法 1 python 的抽象类实现 === 约束性不高 Python是 解释性语言 from abc import ABCMeta from ab ...

  4. InnoDB引擎的特点及优化方法

    1.什么是InnoDB引擎?      InnoDB引擎是MySQL数据库的另一个重要的存储引擎,正成为目前MySQL AB所发行的新版的标准,被包含在所有二进制安装包里,和其他存储引擎相比,Inno ...

  5. CF 739E Gosha is Hunting

    有 $n$ 个 Pokemon,你有 $A$ 个一类精灵球,$B$ 个二类精灵球 分别给出每个 Pokemon 被这两类精灵球捕捉的概率 求抓到 Pokemon 的最优期望个数 $n\leq 2000 ...

  6. [BZOJ1022][SHOI2008]小约翰的游戏

    bzoj luogu sol 显然这个玩意儿和普通\(Nim\)游戏是有区别的. 形式化的,\(Nim\)游戏的关键在于决策集合为空者负,而这里的决策集合为空者胜. 所以就显然不能直接用\(SG\)函 ...

  7. 「新手向」koa2从起步到填坑

    前传 出于兴趣最近开始研究koa2,由于之前有过一些express经验,以为koa还是很好上手的,但是用起来发现还是有些地方容易懵逼,因此整理此文,希望能够帮助到一些新人. 如果你不懂javascri ...

  8. Bootstrap确定样式让屏幕缩小后布局不乱

    解决方案是如下 结果如下:

  9. 如何打开 Windows 的热键提示

    如何打开 Windows 的热键提示 很早之前我记的 Windows 是有热键提示的,不知道什么时候开始默认不显示了,难道 微软是为是美观? 找了一下原来是有地方可以设置的.

  10. 一根Express Route同时支持ARM和ASM的VNET

    ARM模式的Azure管理模式在China Azure上已经正式落地了.今后在China Azure上应该主要以ARM的模式创建VM了. 并且目前Express Route也已经可以在ARM模式下创建 ...