Age of Moyu
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 970 Accepted Submission(s): 264
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
分析:题意:给定n个节点,m条边,每一条边有一个编号,当从一条边走到另一条边时如果两条边的编号相同,则不需要钱,如果两条边的编号不相同,则加1,。
数据好像有点坑,卡常数,听说官方给的标程代码是过不了。。。
我是使用dijkstra堆优化的方法做的,每一条的权责要么是1,要么0,使用优先队列维护就能保证每次从队首吐出来的节点的当前值为对应节点的最小值,即最短路劲。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 100000+100;
int n, m;
struct qnode{
int v;
int c;
int w;
qnode(int _v = 0, int _c = 0, int _w = 0):v(_v),c(_c),w(_w){}
bool operator < (const qnode &r) const{
return c > r.c;
}
};
struct Edge{
int v, cost;
Edge(int _v = 0, int _cost = 0):v(_v),cost(_cost){}
};
vector<Edge> E[maxn];
bool vis[maxn];
int dist[maxn];
void dijkstra(int n, int start){
memset(vis, false, sizeof(vis));
for(int i=0; i<=n; i++){
dist[i] = INF;
}
priority_queue<qnode>que;
while(!que.empty()) que.pop();
dist[start] = 0;
que.push(qnode(start, 0, 0));
qnode tmp;
while(!que.empty()){
tmp = que.top();
que.pop();
int u = tmp.v;
// cout<<u<<endl;
if(vis[u]) continue;
vis[u] = true;
dist[u] = tmp.c;
for(int i=0; i<E[u].size(); i++){
int v = E[u][i].v;
int w1 = E[u][i].cost;
if(!vis[v]){
int temp1;
if(tmp.w != w1) temp1 = tmp.c+1;
else temp1 = tmp.c;
que.push(qnode(v, temp1, w1));
}
}
}
}
void addedge(int u, int v, int w){
E[u].push_back(Edge(v, w));
}
int main(){
while(~scanf("%d%d", &n, &m)){
for(int i=1; i<=n; i++) E[i].clear();
int a, b, w;
for(int i=1; i<=m; i++){
scanf("%d%d%d", &a, &b, &w);
addedge(a, b, w);
addedge(b, a, w);
}
dijkstra(n, 1);
if(dist[n] == INF) printf("-1\n");
else {
printf("%d\n", dist[n]);
}
}
}