这是一道玄学题目。
跑最短路很简单,跑网络流也是模版而已。
但是我跑完最短路后从n开始向前bfs找满足dis[u] == dis[v] + 1的边,然后加入网络流的图里面。这样做会TLE。
然后想了好久实在不知道搞什么鬼,看了看别人代码,别人是直接把所有边for一遍,只要满足dis[u] + 1 == dis[v]的,都加入网络流里面。这样当然也可以,我改了改,15ms就过了。但是这bfs也不至于超时吧???好浪费时间啊,这啥破题啊,本来一小时写完了搞了七个小时,mmp
代码如下:
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<utility>
#include<stack>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
const int maxn = 2005;
const int maxm = 50005;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> pii;
int n, m;
int head[maxn],cur[maxn],nx[maxm<<1],to[maxm<<1],flow[maxm<<1], ppp=0;
int dis[maxn];
struct Dinic
{
int s, t;
int ans;
void init() {
memset(head, -1, sizeof(head));
ppp = 0;
}
void AddEdge(int u, int v, int c)
{
to[ppp]=v;flow[ppp]=c;nx[ppp]=head[u];head[u]=ppp++;swap(u,v);
to[ppp]=v;flow[ppp]=0;nx[ppp]=head[u];head[u]=ppp++;
}
bool BFS()
{
memset(dis, -1, sizeof(dis));
dis[s] = 1;
queue<int> Q;
Q.push(s);
while(!Q.empty())
{
int x = Q.front();
Q.pop();
for(int i = head[x]; ~i; i = nx[i])
{
if(flow[i] && dis[to[i]] == -1)
{
dis[to[i]] = dis[x] + 1;
Q.push(to[i]);
}
}
}
return dis[t] != -1;
}
int DFS(int x, int maxflow)
{
if(x == t || !maxflow){
ans += maxflow;
return maxflow;
}
int ret = 0, f;
for(int &i = cur[x]; ~i; i = nx[i])
{
if(dis[to[i]] == dis[x] + 1 && (f = DFS(to[i], min(maxflow, flow[i]))))
{
ret += f;
flow[i] -= f;
flow[i^1] += f;
maxflow -= f;
if(!maxflow)
break;
}
}
return ret;
}
int solve(int source, int tank)
{
s = source;
t = tank;
ans = 0;
while(BFS())
{
memcpy(cur, head, sizeof(cur));
DFS(s, INF);
}
return ans;
}
}dinic;
vector<pii>edge[maxn];
bool flag[maxn];
void spfa() {
priority_queue <pii, vector<pii>, greater<pii> > q;
int u, v;
pii tmp;
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0;
q.push(pii(0, 1));
while(!q.empty()) {
tmp = q.top();
u = tmp.second;
q.pop();
if(dis[u] < tmp.first)
continue;
if(u == n)
break;
for(int i = 0; i < edge[u].size(); i++) {
tmp = edge[u][i];
v = tmp.first;
if(dis[v] > dis[u] + 1) {
dis[v] = dis[u] + 1;
q.push(pii(dis[v], v));
}
}
}
}
//void findpath() {
// int u, v;
// queue <int> q;
// q.push(n);
// while(!q.empty()) {
// u = q.front();
// q.pop();
// if(u == 1)
// break;
//
// for(int i = 0; i < edge[u].size(); i++) {
// v = edge[u][i].first;
// if(dis[v] + 1 == dis[u]) {
// dinic.AddEdge(v, u, edge[u][i].second);
// q.push(v);
// }
// }
// }
//}
void findpath() {
int v;
for(int i = 1; i <= n; i++) {
for(int j = 0; j < edge[i].size(); j++) {
v = edge[i][j].first;
if(dis[v] == dis[i] + 1) {
dinic.AddEdge(i, v, edge[i][j].second);
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < maxn; i++) {
edge[i].clear();
}
dinic.init();
int u, v, val;
while(m--) {
scanf("%d%d%d", &u, &v, &val);
edge[u].push_back(pii(v, val));
edge[v].push_back(pii(u, val));
}
spfa();
findpath();
int ans = dinic.solve(1, n);
printf("%d\n", ans);
}
return 0;
}