题目大意
给出一个无向图,求出在这个图上1到n的所有最短路形成的图的最大流。
思路
想让大家叠模板也不带这么懒得吧。。
记得开long long就行了。
CODE
#define _CRT_SECURE_NO_WARNINGS
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXP 10010
#define MAXE 1000010
#define S 0
#define T (MAXP - 1)
#define INF 0x3f3f3f3f3f3f3f3fll
using namespace std;
struct MaxFlow{
int head[MAXP], total;
int _next[MAXE], aim[MAXE];
long long flow[MAXE];
int deep[MAXP];
MaxFlow():total(1) {}
void Add(int x, int y, long long f) {
_next[++total] = head[x];
aim[total] = y;
flow[total] = f;
head[x] = total;
}
void Insert(int x, int y, long long f) {
Add(x, y, f);
Add(y, x, 0);
}
bool BFS() {
static queue<int> q;
while(!q.empty()) q.pop();
memset(deep, 0, sizeof(deep));
deep[S] = 1;
q.push(S);
while(!q.empty()) {
int x = q.front(); q.pop();
for(int i = head[x]; i; i = _next[i])
if(flow[i] && !deep[aim[i]]) {
deep[aim[i]] = deep[x] + 1;
q.push(aim[i]);
if(aim[i] == T) return true;
}
}
return false;
}
long long Dinic(int x, long long f) {
if(x == T) return f;
long long temp = f;
for(int i = head[x]; i; i = _next[i])
if(flow[i] && deep[aim[i]] == deep[x] + 1 && temp) {
long long away = Dinic(aim[i], min(flow[i], temp));
if(!away) deep[aim[i]] = 0;
flow[i] -=away;
flow[i^1] += away;
temp -= away;
}
return f - temp;
}
}solver;
struct Edge{
int x, y, z;
void Read() {
scanf("%d%d%d", &x, &y, &z);
}
}edge[MAXE];
int points, edges;
int head[MAXP], total;
int _next[MAXE], aim[MAXE];
long long length[MAXE];
inline void Add(int x, int y, long long len)
{
_next[++total] = head[x];
aim[total] = y;
length[total] = len;
head[x] = total;
}
long long l1[MAXP], l2[MAXP];
bool v[MAXP];
void Dijkstra(int start, long long f[])
{
memset(v, false, sizeof(v));
f[start] = 0;
for(int i = 1; i <= points; ++i) {
long long min_length = INF;
int p;
for(int j = 1; j <= points; ++j)
if(!v[j] && f[j] < min_length)
min_length = f[j], p = j;
v[p] = true;
for(int j = head[p]; j; j = _next[j])
if(!v[aim[j]])
f[aim[j]] = min(f[aim[j]], f[p] + length[j]);
}
}
int main()
{
cin >> points >> edges;
for(int i = 1; i <= edges; ++i) {
edge[i].Read();
Add(edge[i].x, edge[i].y, edge[i].z);
Add(edge[i].y, edge[i].x, edge[i].z);
}
for(int x, i = 1; i <= points; ++i) {
scanf("%d", &x);
solver.Insert(i << 1, i << 1|1, (i == 1 || i == points) ? INF:x);
}
memset(l1, 0x3f, sizeof(l1));
memset(l2, 0x3f, sizeof(l2));
Dijkstra(1, l1);
Dijkstra(points, l2);
long long min_length = l2[1];
for(int i = 1; i <= edges; ++i) {
if(l1[edge[i].x] + l2[edge[i].y] + edge[i].z == min_length)
solver.Insert(edge[i].x << 1|1, edge[i].y << 1, INF);
if(l2[edge[i].x] + l1[edge[i].x] + edge[i].z == min_length)
solver.Insert(edge[i].y << 1|1, edge[i].x << 1, INF);
}
solver.Insert(S, 2, INF);
solver.Insert(points << 1|1, T, INF);
long long max_flow = 0;
while(solver.BFS())
max_flow += solver.Dinic(S, INF);
cout << max_flow << endl;
return 0;
}
时间: 2024-10-10 20:45:34