多么裸的一个网络流 可是我爆0了
inf要开的非常非常大才行 每一个数据都非常非常大 QAQ 长教训了
先从n跑一遍最短路 然后从1开始宽搜 最短路径上的边才连入图中 然后每个点拆点 跑最大流就行了
这么仁慈 这么裸 这么水的网络流 我居然爆0了
果然像我这样的人最好早点滚粗
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 500 * 2;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
const LL inf = 1LL * MAXM * 1000000000;
int n, m, val[MAXN+10], S, T;
int cnt, cho[MAXN+10];
struct Node {
int u, v, next;
LL c;
} ;
struct ISAP {
int gap[MAXN*2+10], d[MAXN*2+10];
int adj[MAXN*2+10], ecnt;
int n, m, s, t;
Node Edge[MAXM*4+10];
void init() {
memset(adj, -1, sizeof(adj));
}
void addedge(int u, int v, LL c) {
Node &e = Edge[ecnt];
e.v = v; e.u = u; e.c = c; e.next = adj[u];
adj[u] = ecnt++;
m = ecnt;
}
void add(int u, int v, LL c) {
addedge(u, v, c); addedge(v, u, 0);
}
void init_dis() {
queue <int> q;
memset(d, -1, sizeof(d));
memset(gap, 0, sizeof(gap));
d[t] = 0; q.push(t); cnt = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
gap[d[u]]++;
for(int i = adj[u]; ~i; i = Edge[i].next) {
int v = Edge[i].v;
if(d[v] == -1) d[v] = d[u] + 1, q.push(v), cnt++;
}
}
}
LL aug(int u, LL inc) {
int mindis = n-1;
LL Inc = 0;
if(u == t) return inc;
for(int i = adj[u]; ~i; i = Edge[i].next) {
Node &e = Edge[i];
int v = e.v;
LL c = e.c;
if(c) {
if(d[v] == d[u] - 1) {
LL del = min(1LL * c, inc - Inc);
del = aug(v, del);
Inc += del;
Edge[i].c -= del;
Edge[i^1].c += del;
if(d[s] >= n) return Inc;
if(inc == Inc) return Inc;
}
mindis = min(mindis, d[v]);
}
}
if(!Inc) {
gap[d[u]]--;
if(gap[d[u]] == 0) d[s] = n;
d[u] = mindis + 1;
gap[d[u]]++;
}
return Inc;
}
LL Maxflow(int _s, int _t, int _n) {
n = _n; s = _s; t = _t;
LL Flow = 0;
init_dis();
n = cnt;
while(d[s] < n)
Flow += aug(s, inf);
return Flow;
}
} sap;
Node edge[MAXM*2+10];
int Adj[MAXN+10], Ecnt;
bool vis[MAXN+10];
LL dis[MAXN+10];
queue <int> q;
void addedge(int u, int v, int wt) {
Node &e = edge[Ecnt];
e.v = v; e.c = wt; e.next = Adj[u]; Adj[u] = Ecnt++;
} ;
void SPFA() {
for(int i = 1; i <= n; i++) dis[i] = inf;
dis[n] = 0; q.push(n);
while(!q.empty()) {
int u = q.front(); q.pop();
vis[u] = false;
for(int i = Adj[u]; ~i; i = edge[i].next) {
int v = edge[i].v, wt = edge[i].c;
if(dis[v] > dis[u] + wt) {
dis[v] = dis[u] + wt;
if(!vis[v]) vis[v] = true, q.push(v);
}
}
}
}
void Build_Graph() {
q.push(1);
memset(vis, 0, sizeof(vis));
vis[1] = true;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = Adj[u]; ~i; i = edge[i].next) {
int v = edge[i].v, wt = edge[i].c;
if(dis[v] == dis[u] - wt) {
sap.add(u+n, v, INF);
if(!vis[v]) vis[v] = true, q .push(v);
}
}
}
}
int main() {
memset(Adj, -1, sizeof(Adj));
sap.init();
SF("%d%d", &n, &m);
S = 1; T = n;
for(int i = 1; i <= m; i++) {
int u, v, wt;
SF("%d%d%d", &u, &v, &wt);
addedge(u, v, wt);
addedge(v, u, wt);
}
for(int i = 1; i <= n; i++) SF("%d", &val[i]);
SPFA();
Build_Graph();
for(int i = 2; i < n; i++) sap.add(i, i+n, val[i]);
sap.add(1, n+1, inf);
LL ans = sap.Maxflow(S, T, n*2-1);
cout << ans;
}