題目鏈接:
2018 Multi-University Training Contest 7 Age of Moyu HDU - 6386
題意概括:
給一幅圖,N個節點,M條雙向邊。與以往不同的是並沒有給出邊權,而給出佔有這條邊的主人編號。在兩條同一個主人的邊上切換時不需要花費,而不同主人時需要花費 1 。例如,從 A 主人到 B 主人的邊需要花費 1 ,從 B 的邊回到 A 的邊時,還依然需要花費 1 。要求求出從節點 1 到 N 的最少花費,若到不了,則輸出 -1 。
數據範圍:
測試數據不超過 20 組
,
,
題解分析:
就是單源最短路問題,每條邊的權值賦爲 1 ,把 Dijkstra算法 改寫一下即可。此題和裸的單源最短路唯一區別就是多了一個條件:同一個主人的邊之間切換不需要花費。所以,需要改寫的地方就是鬆弛。假如鬆弛的時候,兩條邊相鄰並且同主,就把cost 設爲 0 即可。這裏需要維護一個數組,儲存原點到其他點的最短路過程中,經過的最後一條邊的主人編號。
AC代碼:
#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
struct qnode
{
int v;
int c;
qnode(int _v = 0, int _c = 0): v(_v), c(_c) {}
bool operator < (const qnode &r)const
{
return c > r.c;
}
};
struct Edge
{
int v, cost,own;
Edge(int _v = 0, int _cost = 0, int _own = 0): v(_v), cost(_cost),own(_own) {}
};
vector<Edge>E[MAXN];
bool vis[MAXN];
int dist[MAXN];
int own[MAXN];
void Dijkstra(int n, int start) //點的編號從1開始,有n個點
{
memset(vis, false, sizeof(vis)); //初始化vis
for (int i = 1; i <= n; i ++) {dist[i] = INF; own[i] = -1;}
//初始化dist
priority_queue<qnode>que;
while (!que.empty())
que.pop();
dist[start] = 0;
que.push(qnode(start, 0));
qnode tmp;
while (!que.empty())
{
tmp = que.top(); que.pop();
int u = tmp.v;
if (vis[u]) continue;
vis[u] = true;
for (int i = 0; i < E[u].size(); i ++)
{
int v = E[tmp.v][i].v, cost;
if (own[u] == E[u][i].own)
cost = 0;
else
cost = E[u][i].cost;
if (!vis[v] && dist[v] > dist[u] + cost)
{
dist[v] = dist[u] + cost;
own[v] = E[u][i].own;
que.push(qnode(v, dist[v]));
}
}
}
}
void addedge(int u, int v, int w,int own)//起點、終點、權重
{
E[u].push_back(Edge(v, w, own));
}
int main() {
int N, M;
while (scanf("%d%d", &N, &M) != EOF) {
if (M == 0) {printf("-1\n"); continue;}
for (int i = 0; i <= N; i ++) E[i].clear(); //每次都要初始化vector<Edge>E[MAXN];
for (int i = 0; i < M; i ++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
addedge(b, a, 1, c);
addedge(a, b, 1, c);
}
Dijkstra(N, 1);
if ( dist[N] == INF)
printf("-1\n");
else
printf("%d\n", dist[N]);
}
}
Age of Moyu
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
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