| 
 
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <cmath>
 #include <set>
 #include <vector>
 #include <map>
 #include <queue>
 #include <set>
 #include <algorithm>
 #include <limits.h>
 using namespace std;
 typedef long long LL;
 const int MAXN=1e+4;
 const int MAXM=1e+6;
 const int INF=INT_MAX;
 struct Edge
 {
 int from,to,ci,next;
 Edge(){}
 Edge(int _from,int _to,int _ci,int _next):from(_from),to(_to),ci(_ci),next(_next){}
 }e[MAXM];
 int head[MAXN],tot;
 int dis[MAXN];
 int top,sta[MAXN],cur[MAXN];
 inline void init(){
 memset(head,-1,sizeof(head));
 tot=0;
 }
 inline void AddEdge(int u,int v,int ci0,int ci1=0){
 e[tot]=Edge(u,v,ci0,head[u]);
 head[u]=tot++;
 e[tot]=Edge(v,u,ci1,head[v]);
 head[v]=tot++;
 }
 inline bool bfs(int st,int et){
 memset(dis,0,sizeof(dis));
 dis[st]=1;
 queue <int> q;
 q.push(st);
 while(!q.empty()){
 int now=q.front();
 q.pop();
 for(int i=head[now];i!=-1;i=e[i].next){
 int next=e[i].to;
 if(e[i].ci&&!dis[next]){
 dis[next]=dis[now]+1;
 if(next==et)return true;
 q.push(next);
 }
 }
 }
 return false;
 }
 LL Dinic(int st,int et){
 LL ans=0;
 while(bfs(st,et)){
 top=0;
 memcpy(cur,head,sizeof(head));
 int u=st,i;
 while(1){
 if(u==et){
 int pos,minn=INF;
 
 for(i=0;i<top;i++)
 {
 if(minn>e[sta[i]].ci){
 minn=e[sta[i]].ci;
 pos=i;
 }
 
 }
 for(i=0;i<top;i++){
 e[sta[i]].ci-=minn;
 e[sta[i]^1].ci+=minn;
 }
 top=pos;
 u=e[sta[top]].from;
 ans+=minn;
 
 }
 for(i=cur[u];i!=-1;cur[u]=i=e[i].next)
 if(e[i].ci&&dis[u]+1==dis[e[i].to])break;
 if(cur[u]!=-1){
 sta[top++]=cur[u];
 u=e[cur[u]].to;
 }
 else {
 if(top==0)break;
 dis[u]=0;
 u=e[sta[--top]].from;
 }
 }
 }
 return ans;
 }
 struct point
 {
 int to,v;
 point(){}
 point(int _to,int _v):to(_to),v(_v){}
 };
 vector <point> e1[MAXN];
 int disx[MAXN],in[MAXN];
 void bfs1(int st){
 memset(disx,-1,sizeof(disx));
 in[st]=1;
 disx[st]=0;
 queue <int> q;
 q.push(st);
 while(!q.empty()){
 int now=q.front();
 q.pop();
 in[now]=0;
 for(int i=0;i<(int)e1[now].size();i++){
 point tmp=e1[now][i];
 int next=tmp.to;
 if(disx[next]==-1||disx[now]+tmp.v<disx[next]){
 disx[next]=disx[now]+tmp.v;
 if(!in[next]){
 in[next]=1;
 q.push(next);
 }
 }
 }
 }
 }
 int main()
 {
 int t,n,m,st,et;
 scanf("%d",&t);
 while(t--){
 scanf("%d%d",&n,&m);
 for(int i=0;i<=n;i++)
 e1[i].clear();
 for(int i=0,x,y,v;i<m;i++){
 scanf("%d%d%d",&x,&y,&v);
 e1[x].push_back(point(y,v));
 }
 scanf("%d%d",&st,&et);
 bfs1(st);
 init();
 for(int i=1;i<=n;i++){
 for(int j=0;j<(int)e1[i].size();j++){
 point tmp=e1[i][j];
 if(disx[i]+tmp.v==disx[tmp.to]){
 AddEdge(i,tmp.to,1);
 
 }
 }
 }
 printf("%I64d\n",Dinic(st,et));
 }
 return 0;
 }
 
 
 |