任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6386
Age of Moyu
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 3821 Accepted Submission(s): 1214
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)
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.
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条无向边,每条边都有编号,经过相同的编号的边不会改变花费,经过不同的编号的边花费加一。
解题思路:
BFS 求最短路,用边替换点进队,按照花费升序排序。
可能数据偏水,可以卡过去。
AC code:
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 #define LL long long 4 using namespace std; 5 6 const int MAXN = 1e5+10; 7 bool vis[MAXN]; 8 int N, M; 9 10 struct Edge 11 { 12 int nxt, no, v; 13 }edge[MAXN<<2]; 14 int head[MAXN], tot; 15 void init() 16 { 17 memset(vis, 0, sizeof(vis)); 18 memset(head, -1, sizeof(head)); 19 tot = 0; 20 } 21 22 void add(int a, int b, int no) 23 { 24 edge[tot].v = b; 25 edge[tot].no = no; 26 edge[tot].nxt = head[a]; 27 head[a] = tot++; 28 } 29 30 struct data 31 { 32 int u, v, cnt, type; 33 bool operator < (const data &a) const { 34 return cnt > a.cnt; 35 } 36 }; 37 38 39 int solve() 40 { 41 data x, y; 42 int from, to, t, vv, sum; 43 priority_queue<data>quq; 44 for(int i = head[1]; i != -1; i = edge[i].nxt){ 45 x.u = 1; 46 x.v = edge[i].v; 47 x.cnt = 1; 48 x.type = edge[i].no; 49 quq.push(x); 50 } 51 vis[1] = true; 52 while(!quq.empty()){ 53 x = quq.top(); 54 quq.pop(); 55 to = x.v; 56 t = x.type; 57 sum = x.cnt; 58 if(to == N) return sum; 59 vis[to] = true; 60 for(int i = head[to]; i != -1; i = edge[i].nxt){ 61 vv = edge[i].v; 62 if(vis[vv]) continue; 63 if(edge[i].no != t) y.cnt = sum+1; 64 else y.cnt = sum; 65 y.v = vv; 66 y.type = edge[i].no; 67 quq.push(y); 68 } 69 } 70 return -1; 71 } 72 73 int main() 74 { 75 int u, v, no; 76 while(~scanf("%d %d", &N, &M)){ 77 init(); 78 for(int i = 1; i <= M; i++){ 79 scanf("%d %d %d", &u, &v, &no); 80 add(u, v, no); 81 add(v, u, no); 82 } 83 84 int ans = solve(); 85 printf("%d ", ans); 86 } 87 return 0; 88 }