http://acm.hdu.edu.cn/showproblem.php?pid=4360
题意:
有n个点 ,m条边,没条边 哟 4 个属性 起点 u 终点v 长度 l 和 编号 k (k为 L,O,V,E 中的任意一个),求 从1 到n 点的 一条路,要求 含有完整的 1个 或多个 love 串 ,且是 最短的
每条边除了有边权以外,还有一个字母标记。标记可以是“LOVE”里面任意字符。
每个点,要拆成四个点,分别代表到达该点的标记为L,O,V,E的最短路。
第一步就是求最短路,直接spfa就可以了。
trick在于,至少要找到一个LOVE串,在只有一个节点的时候,有几条自环,至少必须走LOVE四条自环。此时,必须另外加一个节点表示开始节点。
还有一个trick就是距离可能超过int。
1 2 1314520 L
1 2 1314520 O
1 2 1314520 V
2 3 1314520 E
3 4 1314520 L
3 4 1314520 O
3 4 1314520 V
4 5 1314520 E
...
这种情况下1313个点,2624条边,每条边长度1314520,并且每条边都必须走,所以,超int了(至少signed不够)。
SPFA跑一趟就可以了。
1 include<stdio.h>
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cmath>
6 #include<queue>
7 #include<
set>
8 #include<map>
9
#define Min(a,b) a>b?b:a
10
#define Max(a,b) a>b?a:b
11
#define CL(a,num) memset(a,num,sizeof(a));
12
#define inf 9999999
13
#define maxn 1500
14
#define mod 100000007
15
#define eps 1e-6
16
#define ll long long
17
#define M 15520
18
using
namespace std;
19 map<
char,
int>map1;
20 __int64 dis[maxn][
4];
21 __int64 step[maxn][
4];
22
int head[maxn] ;
23
struct edge
24 {
25
int v;
26
int len ;
27
int k;
28
int next;
29
30 }p[M*
2];
31
struct node
32 {
33
int u;
34 __int64 len;
35 __int64 stp;
36
int k ;
37 node(
int x,__int64 y,
int z,
int w):u(x),len(y),stp(z),k(w){}
38
39 };
40
int num ,n,m;
41
void add(
int x,
int y,
int len,
int k)
42 {
43 p[num].v = y;
44 p[num].len = len;
45 p[num].k = k;
46 p[num].next = head[x];
47 head[x] = num++;
48
49 }
50
void init()
51 {
52 num =
0;
53 memset(dis,
0x3f,
sizeof(dis));
54 CL(step,
0);
55 CL(head,-
1);
56 }
57
void SPFA()
58 {
59
int i ;
60 queue<node>que;
61 que.push(node(
1,
0,
0,
3));
62
while(!que.empty())
63 {
64
65 node a = que.front();que.pop();
66
int u = a.u;
67
int k = (a.k +
1)%
4;
68 __int64 len = a.len ;
69 __int64 stp = a.stp;
70
71
for(i = head[u];i != -
1;i = p[i].next)
72 {
73
74
int v = p[i].v;
75
//
printf("%d %d +++\n",u,v);
76
77
if(k == p[i].k )
78 {
79
if(dis[v][k] > len + p[i].len || dis[v][k] == len + p[i].len && step[v][k] < stp +
1)
80 {
81 dis[v][k] = len + p[i].len;
82 step[v][k] = stp +
1;
83 que.push(node(v,dis[v][k],step[v][k],k));
84
85 }
86 }
87 }
88 }
89
90
91
92
93 }
94
int main()
95 {
96 map1[
'
L
'] =
0;
97 map1[
'
O
'] =
1;
98 map1[
'
V
'] =
2;
99 map1[
'
E
'] =
3;
100
int t,i,x,y,d;
101
char c[
3] ;
102 scanf(
"
%d
",&t);
103
int cas =
0;
104
while(t--)
105 {
106 scanf(
"
%d%d
",&n,&m);
107 init();
108
for( i =
0 ; i < m;++i )
109 {
110 scanf(
"
%d %d %d %s
",&x,&y,&d,c);
111 add(x,y,d,map1[c[
0]]);
112 add(y,x,d,map1[c[
0]]);
113 }
114
115 SPFA();
116
if(dis[n][
3] == dis[n+
1][
0])
117 {
118 printf(
"
Case %d: Binbin you disappoint Sangsang again, damn it!\n
",++cas);
119 }
120
else
121 {
122 printf(
"
Case %d: Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %I64d LOVE strings at last.\n
",++cas,dis[n][
3],step[n][
3]/
4);
123 }
124
125 }
126
127 }