多么裸的一个网络流 可是我爆0了
inf要开的非常非常大才行 每一个数据都非常非常大 QAQ 长教训了
先从n跑一遍最短路 然后从1开始宽搜 最短路径上的边才连入图中 然后每个点拆点 跑最大流就行了
这么仁慈 这么裸 这么水的网络流 我居然爆0了
果然像我这样的人最好早点滚粗
#include #include #include #include #include #include #include #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 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 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; }