/*
题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点的最短路一共有多少条。这是一个有向图,建边的时候要注意!!
解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短路的题目接触过很多,反向建一个图,求两边最短路,即从src到任一点的最短路dis1[]和从des到任一点的最短路dis2[],那么假设这条边是(u,v,w),如果dis1[u] + w + dis2[v] = dis1[des],说明这条边是构成最短路的边。找到这些边,就可以把边的容量设为1,跑一边最大流即可。
————————————————
代码:

1 #include<stdio.h>
2 #include<algorithm>
3 #include<string.h>
4 #include<queue>
5 using namespace std;
6 const int maxn = 1005;
7 const int inf = 0x3f3f3f3f;
8 int t, u, v, w;
9 struct node
10 {
11 int u, v, w, next;
12 }edge[800005], e[100005];
13 int head[maxn], dis[2][maxn], pre[2][maxn],level[maxn];
14 bool vis[maxn];
15 int n, m, st, ed, tot;
16 void init()
17 {
18 tot = 0;
19 memset(head, -1, sizeof(head));
20 memset(pre, -1, sizeof(pre));
21 return;
22 }
23 void addedge(int u, int v, int w)
24 {
25 edge[tot].v = v;
26 edge[tot].w = w;
27 edge[tot].next = head[u];
28 head[u] = tot++;
29 edge[tot].v = u;
30 edge[tot].w = w;
31 edge[tot].next = head[v];
32 head[v] = tot++;
33 return;
34 }
35 void addedge1(int u,int v,int w)
36 {
37 edge[tot].v = v;
38 edge[tot].w = w;
39 edge[tot].next = pre[0][u];
40 pre[0][u] = tot++;
41 return;
42 }
43 void addedge2(int u, int v, int w)
44 {
45 edge[tot].v = v;
46 edge[tot].w = w;
47 edge[tot].next = pre[1][u];
48 pre[1][u] = tot++;
49 return;
50 }
51 void spfa(int st, int ed, int idx)
52 {
53 queue<int>pq;
54 memset(dis[idx], inf, sizeof(dis[idx]));
55 memset(vis, false, sizeof(vis));
56 dis[idx][st] = 0;
57 pq.push(st);
58 vis[st] = true;
59 while (!pq.empty())
60 {
61 int u = pq.front();
62 pq.pop();
63 vis[u] = false;
64 for (int i = pre[idx][u]; i != -1; i = edge[i].next)
65 {
66 int v = edge[i].v;
67 if(dis[idx][v] > dis[idx][u] + edge[i].w)
68 {
69 dis[idx][v] = dis[idx][u] + edge[i].w;
70 if (!vis[v])
71 {
72 pq.push(v);
73 vis[v] = true;
74 }
75 }
76 }
77 }
78 }
79 void build()
80 {
81 for (int i = 1; i <= m; i++)
82 {
83 u = e[i].u;
84 v = e[i].v;
85 w = e[i].w;
86 if (dis[0][u] + dis[1][v] + w == dis[0][ed])
87 {
88 addedge(u, v, 1);
89 }
90 }
91 }
92 int bfs(int st, int ed)
93 {
94 queue<int>q;
95 memset(level, 0, sizeof(level));
96 level[st] = 1;
97 q.push(st);
98 while (!q.empty())
99 {
100 int u = q.front();
101 q.pop();
102 if (u == ed)
103 {
104 return 1;
105 }
106 for (int i = head[u]; i != -1; i = edge[i].next)
107 {
108 int v = edge[i].v;
109 int w = edge[i].w;
110 if (level[v] == 0 && w != 0)
111 {
112 level[v] = level[u] + 1;
113 q.push(v);
114 }
115 }
116 }
117 return -1;
118 }
119 int dfs(int st, int ed, int f)
120 {
121 if (st == ed)
122 {
123 return f;
124 }
125 int ret = 0;
126 for (int i = head[st]; i != -1; i = edge[i].next)
127 {
128 int v = edge[i].v;
129 int w = edge[i].w;
130 if (level[v] == level[st] + 1 && w != 0)
131 {
132 int MIN = min(f - ret, w);
133 w = dfs(v, ed, MIN);
134 if (w > 0)
135 {
136 edge[i].w -= w;
137 edge[i ^ 1].w += w;
138 ret += w;
139 if (ret == f)
140 {
141 return ret;
142 }
143 }
144 else
145 {
146 level[v] = -1;
147 }
148 }
149 }
150 return ret;
151 }
152 int dinic(int st,int ed)
153 {
154 int ans = 0;
155 while (bfs(st, ed) != -1)
156 {
157 ans += dfs(st, ed, inf);
158 }
159 return ans;
160 }
161 int main()
162 {
163 //freopen("C:/input.txt", "r", stdin);
164 scanf("%d", &t);
165 while (t--)
166 {
167 init();
168 scanf("%d%d", &n, &m);
169 for (int i = 1; i <= m; i++)
170 {
171 scanf("%d%d%d", &u, &v, &w);
172 e[i].u = u, e[i].v = v, e[i].w = w;
173 addedge1(u, v, w);
174 addedge2(v, u, w);
175 }
176 scanf("%d%d", &st, &ed);
177 spfa(st, ed, 0);
178 spfa(ed, st, 1);
179 build();
180 int maxflow = dinic(st, ed);
181 printf("%d\n", maxflow);
182 }
183 return 0;
184 }
