题目链接:https://cn.vjudge.net/problem/HDU-3416
/*
Marriage Match IV
HDU - 3416
https://cn.vjudge.net/problem/HDU-3416
题意: 找出所有最短路的个数
解法:
双向SPFA枚举每条边找出最短路的连通图
最大流求最短路个数
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f
#define maxn 100010
struct node{
int u, v, w;
int next;
}edge[maxn], uedge[maxn], wedge[maxn*2];
int head[maxn], uhead[maxn], whead[maxn];
int cnt, ucnt, wcnt;
int dis[maxn], udis[maxn];
int d[maxn];
int t,n,B,E;
void init(){
memset(head, -1, sizeof head);
memset(uhead, -1, sizeof uhead);
memset(whead, -1, sizeof whead);
memset(dis, INF, sizeof dis);
memset(udis, INF, sizeof udis);
cnt = ucnt = wcnt = 0;
}
void add(int u, int v, int w, node edge[], int &cnt, int *head){
edge[cnt].w=w;
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void add_dinic(int u,int v,int w){
wedge[wcnt].w=w;
wedge[wcnt].u=u;
wedge[wcnt].v=v;
wedge[wcnt].next=whead[u];
whead[u]=wcnt++;
wedge[wcnt].w=0;
wedge[wcnt].u=v;
wedge[wcnt].v=u;
wedge[wcnt].next=whead[v];
whead[v]=wcnt++;
}
void spfa(int st, int *dis, int *head, node edge[]){
queue<int> q;
bool color[maxn];
memset(color,true,sizeof color);
q.push(st);
dis[st]=0;
color[st]=false;
while(!q.empty()){
int u=q.front();
q.pop();
color[u]=true;
for(int i=head[u];~i;i=edge[i].next){
if(dis[u]+edge[i].w<dis[edge[i].v]){
dis[edge[i].v]=dis[u]+edge[i].w;
if(color[edge[i].v]){
q.push(edge[i].v);
color[edge[i].v]=false;
}
}
}
}
}
bool bfs(int B,int E){
memset(d,-1,sizeof d);
queue<int> q;
d[B]=0;
q.push(B);
while(!q.empty()){
int st=q.front();
q.pop();
for(int i=whead[st];~i;i=wedge[i].next){
if(d[wedge[i].v]==-1&&wedge[i].w>0){
d[wedge[i].v]=d[st]+1;
q.push(wedge[i].v);
}
}
}
return d[E]!=-1;
}
int dfs(int a,int b){
int r=0;
if(a==E) return b;
for(int i=whead[a];~i;i=wedge[i].next){
if(wedge[i].w>0&&d[wedge[i].v]==d[a]+1){
int x=min(wedge[i].w,b-r);
x=dfs(wedge[i].v,x);
r+=x;
wedge[i].w-=x;
wedge[i^1].w+=x;
}
}
if(!r) d[a]=-2;
return r;
}
int dinic(int B,int E){
int ans=0;
int t;
while(bfs(B,E)){
while(t=dfs(B,INF)) ans+=t;
}
return ans;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d %d", &n, &t);
init();
for(int i=0;i<t;i++){
int u,v,w;
scanf("%d %d %d", &u, &v, &w);
add(u, v, w, edge, cnt, head);
add(v, u, w, uedge, ucnt, uhead);
}
scanf("%d %d", &B ,&E);
spfa(B, dis, head, edge);
if(dis[E]==INF){
printf("0\n");
continue;
}
long long tmp = dis[E];
spfa(E, udis, uhead, uedge);
for(int i=0;i<t;i++){
int u=edge[i].u,v=edge[i].v;
if(edge[i].w&&dis[u]+udis[v]+edge[i].w==tmp){
add_dinic(u,v,1);
}
}
printf("%d\n", dinic(B,E));
}
return 0;
}