Age of Moyu
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2178 Accepted Submission(s): 673
Problem Description
Mr.Quin love fishes so much and Mr.Quin’s city has a nautical system,consisiting of N ports and M shipping lines. The ports are numbered 1 to N. Each line is occupied by a Weitian. Each Weitian has an identification number.
The i-th (1≤i≤M) line connects port Ai and Bi (Ai≠Bi) bidirectionally, and occupied by Ci Weitian (At most one line between two ports).
When Mr.Quin only uses lines that are occupied by the same Weitian, the cost is 1 XiangXiangJi. Whenever Mr.Quin changes to a line that is occupied by a different Weitian from the current line, Mr.Quin is charged an additional cost of 1 XiangXiangJi. In a case where Mr.Quin changed from some Weitian A's line to another Weitian's line changes to Weitian A's line again, the additional cost is incurred again.
Mr.Quin is now at port 1 and wants to travel to port N where live many fishes. Find the minimum required XiangXiangJi (If Mr.Quin can’t travel to port N, print −1instead)Input
There might be multiple test cases, no more than 20. You need to read till the end of input.
For each test case,In the first line, two integers N (2≤N≤100000) and M (0≤M≤200000), representing the number of ports and shipping lines in the city.
In the following m lines, each contain three integers, the first and second representing two ends Ai and Bi of a shipping line (1≤Ai,Bi≤N) and the third representing the identification number Ci (1≤Ci≤1000000) of Weitian who occupies this shipping line.Output
For each test case output the minimum required cost. If Mr.Quin can’t travel to port N, output −1 instead.
Sample Input
3 3
1 2 1
1 3 2
2 3 1
2 0
3 2
1 2 1
2 3 2
Sample Output
1
-1
2
Source
题意:
给你n个点与m条边,想需要从1到n,每个点可能由不同的公司运营,当你切换道路时,花费需要+1,然后让你求最小花费,如不能到底n,就输出-1.
题解:
别看题面花哨,就计算切换不同公司运营路线次数+1就好,但是不能直接跑Dijkstra,会直接TLE,要加个堆优化,或者用优先队列应该能过,这里使用集合记录点,使用优先队列优化的bfs计算花费。
算法:
bfs,前向星。
这里正好学习了一下前向星,懵懵懂懂的,还是不会用啊T.T。
前向星:一般来讲,图的常用存储结构有邻接矩阵,和邻接表,但我们知道邻接矩阵空间浪费太严重,邻接表不好写,今天来讲一下图的另一只常用的存储结构:前向星和链式前向星,介于上述两种存储结构之间的一种比较均衡的存储结构。创造人:https://malash.me/200910/linked-forward-star/
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 +10;
const int inf = 0x3f3f3f3f;
int n,m,k,t,h[N],tot;
int num[N],ans[N];
struct owo {
int v,id,next;
} edges[N<<2];
int head[N];
int dis[N];
set<int> sta[N];
void init() {
tot = 0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int id) {//前向星
edges[tot] = (owo) { //初始化,将结构体owo初始化给edge;
v,id,head[u]
};
head[u] = tot++;
}
struct Node {
int val,u;
int pre,fa;
bool operator <(const Node &p)const {//优先队列重载<
return val>p.val;
}
};
void bfs(int s,int t) {
memset(dis,inf,sizeof(dis));
dis[s] = 0;
priority_queue<Node> q;
q.push((Node){//放入起点
dis[s],s,-1,-1
});
while(!q.empty()) {
Node temp = q.top();
q.pop();
int pre = temp.pre;
int u = temp.u;
if(temp.val>dis[u])continue;
else if(temp.val == dis[u]) {
bool tip = true;
if(sta[u].find(pre)!=sta[u].end())
continue;
sta[u].insert(pre);
} else {
dis[u] = temp.val;
sta[u].clear();
sta[u].insert(pre);
}
for(int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].v,now = edges[i].id;
if(v == temp.fa)continue;
if((dis[u]+(pre!=now))<=dis[v]) {
dis[v] = dis[u] + (pre!=now);
if(v!=t)q.push((Node) {
dis[v],v,now,temp.u
});
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE //输入输出挂
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n,m;
int u,v,id;
while(scanf("%d%d",&n,&m)==2) {
for(int i=1; i<=n; ++i) sta[i].clear();
init();
while(m--) {
scanf("%d%d%d",&u,&v,&id);
add(u,v,id);//双向边
add(v,u,id);
}
bfs(1,N);//起点终点
if(dis[n]==inf) dis[n]=-1;
printf("%d\n",dis[n]);
}
}