TOJ 1583: Farm Tour -- 最小費用最大流 MCMF
阿新 • • 發佈:2019-01-22
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define mp make_pair using namespace std; typedef unsigned int ui; typedef long long ll; typedef unsigned long long ull; typedef pair pii; typedef vector vi; typedef vi::iterator vi_it; typedef map mii; typedef priority_queue pqi; typedef priority_queue, greater > rpqi; const int MAX_NODE = 1000 + 10; const int MAX_EDGE = 10000 + 10; const int INF = (int)1.0e9; int p[MAX_NODE]; //predecessor array int d[MAX_NODE]; //cost array(from the source) bool inq[MAX_NODE]; //in-queue flag int cnt = 0; //edge counting int head[MAX_NODE]; struct { int u; int v; int cap; int cost; int next; } edge[MAX_EDGE << 2]; void add_edge(int u, int v, int cap, int cost) { edge[cnt].u = u; edge[cnt].v = v; edge[cnt].cap = cap; edge[cnt].cost = cost; edge[cnt].next = head[u]; head[u] = cnt++; edge[cnt].u = v; edge[cnt].v = u; edge[cnt].cap = 0; edge[cnt].cost = -cost; edge[cnt].next = head[v]; head[v] = cnt++; } class MCMF { public: /** Description: Arguments: n -- the number of nodes s -- the source t -- the destination Returns:pair */ pii mcmf(int n, int s, int t); }; pii MCMF::mcmf(int n, int s, int t) { queue q; int c = 0; //min cost int f = 0; //max flow int u, v, i; while (true) { memset(inq, 0, sizeof(inq)); for (i = 0; i < n; ++i) { d[i] = INF; } d[s] = 0; q.push(s); inq[s] = true; p[s] = -1; while (!q.empty()) { u = q.front(); q.pop(); inq[u] = false; for (i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if (edge[i].cap > 0 && d[v] > d[u] + edge[i].cost) { d[v] = d[u] + edge[i].cost; p[v] = i; if (!inq[v]) { q.push(v); inq[v] = true; } } } } if (d[t] == INF) { return mp(f, c); } int a = INF; for (i = p[t]; i != -1; i = p[edge[i].u]) { a = min(a, edge[i].cap); } for (i = p[t]; i != -1; i = p[edge[i].u]) { edge[i].cap -= a; edge[i ^ 1].cap += a; } c += d[t] * a; f += a; } return mp(-1, -1); //an error occurs } int main(int argc, char *argv[]) { // freopen("D:\\in.txt", "r", stdin); int n, m; cin >> n >> m; memset(head, -1, sizeof(head)); while (m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); add_edge(u, v, 1, w); add_edge(v, u, 1, w); } add_edge(0, 1, 2, 0); add_edge(n, n + 1, 2, 0); MCMF mc; pii ans = mc.mcmf(n + 2, 0, n + 1); assert(ans.first == 2); cout << ans.second << endl; return 0; }