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

Posted slrslr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ARC061E]すぬけ君の地下鉄旅行 / Snuke's Subway Trip相关的知识,希望对你有一定的参考价值。

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

第$i$条线路($1le i le M$)是直接连接$p_i$与$q_i$的双向铁路,中间不存在其他站点,且这条铁路由$c_i$公司所拥有。

如果乘客只乘坐同一公司的铁路,他只需要花费一元,但如果更换其他公司的铁路需要再花一元。当然,如果你要再换回原来的公司,你还是要花一元。

Snuke在1号站的位置出发,他想通过地铁去第$N$站,请求出最小钱数。如果无法到达第$N$站,输出-1。

最短路建图的好题
首先我们知道,在同一个颜色的联通块内只要一块钱就可以随意走动
那么我们就在这个联通块的入口处连一条长度为1的边,中间连长度为0的边
用map存每个颜色的入口联通块的编号,可知最多有M*2种编号
跑一遍最短路即可,注意答案要除以2(入口和出口都经过了一遍)
代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<map>
 6 #define M 1000010
 7 using namespace std;
 8 int read()
 9 {
10     char ch=getchar();int x=0;
11     while(ch>9||ch<0) ch=getchar();
12     while(ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
13     return x;
14 }
15 struct point{
16     int to,next,dis;
17 }e[M<<1];
18 int n,m,num,cnt;
19 int head[M],dis[M];bool vis[M];
20 void add(int from,int to,int dis)
21 {
22     e[++num].next=head[from];
23     e[num].to=to;
24     e[num].dis=dis;
25     head[from]=num;
26 }
27 void SPFA()
28 {
29     memset(dis,127,sizeof(dis));
30     queue<int>q;
31     q.push(1);
32     vis[1]=true;
33     dis[1]=0;
34     while(!q.empty())
35     {
36         int x=q.front(); q.pop();
37         for(int i=head[x];i;i=e[i].next)
38         {
39             int to=e[i].to;
40             if(dis[to]>dis[x]+e[i].dis)
41             {
42                 dis[to]=dis[x]+e[i].dis;
43                 if(!vis[to])
44                 {
45                     vis[to]=true;
46                     q.push(to);
47                 }
48             }
49         }
50         vis[x]=false;
51     }
52 }
53 map<pair<int,int>,int>P;
54 int get(int x,int y)
55 {
56     if(P.find(make_pair(x,y))!=P.end()) return P[make_pair(x,y)];
57     else return P[make_pair(x,y)]=++cnt;
58 }
59 int main()
60 {
61     n=cnt=read(); m=read();
62     for(int i=1;i<=m;i++)
63     {
64         int a=read(),b=read(),c=read();
65         int id1=get(a,c),id2=get(b,c);
66         add(id1,id2,0); add(id2,id1,0);
67         add(a,id1,1); add(id1,a,1);
68         add(b,id2,1); add(id2,b,1);
69     }
70     SPFA();
71     printf("%d
",dis[n]>2*n?-1:dis[n]/2);
72     return 0;
73 }

 

 

以上是关于[ARC061E]すぬけ君の地下鉄旅行 / Snuke's Subway Trip的主要内容,如果未能解决你的问题,请参考以下文章

ARC 061D すぬけ君の塗り絵 set模拟

すぬけ君の塗り絵 / Snuke's Coloring AtCoder - 2068 (思维,排序,贡献)

AGC 008 A - Simple Calculator

Atcoder 2566 3N Numbers(优先队列优化DP)

AtCoder ARC061E Snuke's Subway Trip 最短路

四月は君の嘘?人生は君の嘘?