题意就是求给定两点间有多少条不含重复边的最短路, 先求出最短路然后构出最短路径图即保留原图中
div[v] == dis[u] + w(u, v)的边然后再跑一遍最大流即可, 注意n = 1时答案为0
#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define fi first
#define se second
#define mp make_pair
typedef int LL;
typedef pair<LL, int> P;
const int N = 1515;
const int M = 2250005;
const LL INF = 1000000000;
struct Dinic {
struct Edge {
int v;
LL cap, flow;
Edge* next, * pair;
void init(int a, LL b, Edge* e1, Edge* e2) {
v = a, cap = b, flow = 0, next = e1, pair = e2;
}
};
Edge* head[N], * used[N];
Edge* it;
int lev[N], que[N];
Edge E[M];
int n, s, t;
LL maxFlow;
void init(int n, int s, int t) {
it = E;
this->n = n;
this->s = s, this->t = t;
for (int i = 0; i <= n; i++)
head[i] = 0;
}
inline void add(int u, int v, LL c) {
it->init(v, c, head[u], it + 1);
head[u] = it++;
it->init(u, 0, head[v], it - 1);
head[v] = it++;
}
bool bfs() {
for (int i = 0; i <= n; lev[i++] = -1);
lev[s] = 0;
int st = 0, ed = 0;
que[ed++] = s;
while (st < ed) {
int u = que[st++];
for (Edge* e = head[u]; e; e = e->next) {
int v = e->v;
if (lev[v] == -1 && e->cap > e->flow) {
lev[v] = lev[u] + 1;
que[ed++] = v;
}
}
}
return lev[t] != -1;
}
LL dfs(int u, LL f) {
if (u == t) return f;
for (Edge* & e = used[u]; e; e = e->next) {
int v = e->v;
if (e->cap > e->flow && lev[v] == lev[u] + 1) {
LL tmp = dfs(v, min(e->cap - e->flow, f));
if (tmp > 0) {
e->flow += tmp;
e->pair->flow -= tmp;
return tmp;
}
}
}
return 0;
}
void run() {
maxFlow = 0;
while (bfs()) {
for (int i = 0; i <= n; i++)
used[i] = head[i];
LL f = 1;
while (f) {
f = dfs(s, INF);
maxFlow += f;
}
}
}
}G2;
struct Dijkstra {
struct Edge {
int v, id;
LL w;
Edge* next;
void init(int a, LL b, Edge* e) {
v = a, w = b, next = e;
}
};
int n, tot;
Edge E[M], * head[N];
LL dis[N];
priority_queue<P, vector<P>, greater<P> > pq;
void init(int n) {
this->n = n;
for (int i = 0; i <= n; i++) {
head[i] = 0;
}
tot = 0;
}
void add(int u, int v, LL w) {
if (u <= 0 || v <= 0) return;
E[tot].init(v, w, head[u]); //******
head[u] = &E[tot++];
E[tot].init(u, w, head[v]);
head[v] = &E[tot++];
}
void run(int s) {
for (int i = 0; i <= n; i++) {
dis[i] = INF;
}
dis[s] = 0;
pq.push(mp(dis[s], s));
while (!pq.empty()) {
P p = pq.top();
pq.pop();
int u = p.se;
if (dis[u] != p.fi) continue;
for (Edge* e = head[u]; e; e = e->next) {
int v = e->v;
if (dis[v] > dis[u] + e->w) {
dis[v] = dis[u] + e->w;
pq.push(mp(dis[v], v));
}
}
}
}
int gao() {
G2.init(n, 1, n);
for (int i = 0; i <= n; i++)
for (Edge* e = head[i]; e; e = e->next) {
int v = e->v;
if (dis[v] == dis[i] + e->w) {
G2.add(i, v, 1);
}
}
G2.run();
return G2.maxFlow;
}
}G;
int main() {
int test, n, u, v, w;
scanf("%d", &test);
while (test--) {
scanf("%d", &n);
G.init(n);
while (scanf("%d%d%d", &u, &v, &w), u + v + w) {
G.add(u, v, w);
}
if (n == 1) {
puts("0");
continue;
}
G.run(1);
printf("%d\n", G.gao());
}
return 0;
}