POJ 1459--最大流算法
cin竟然比scanf慢了十几倍,想不通
#include <iostream> #include <string> #include <vector> #include <cstdlib> #include <cmath> #include <map> #include <algorithm> #include <list> #include <ctime> #include <set> #include <queue> #include <cstring> #include <cstdio> using namespace std; #define INT_MAX 10000000 #define N 105 #define CLR(arr, what) memset(arr, what, sizeof(arr)) int capacity[N][N]; //容量 int flow[N]; //残余流量 int pre[N]; //前趋 int n; //节点个数 queue<int> Q; int BFS(int src, int des) { //初始化 while (!Q.empty()) { Q.pop(); } for (int i = 1; i < n + 1; i++) { pre[i] = -1; } pre[src] = 0; flow[src] = INT_MAX; //初始化源点的流量为无穷大 Q.push(src); while (!Q.empty()) { int index = Q.front(); Q.pop(); if (index == des) { //找到了增广路径 break; } for (int i = 1; i < n + 1; i++) { if (i != src && capacity[index][i] > 0 && pre[i] == -1) { pre[i] = index; //增广路残容流量 flow[i] = min(capacity[index][i], flow[index]); Q.push(i); } } } //while if (pre[des] == -1) { return -1; //残留图中不存在增广路径 } else { return flow[des]; } } int MaxFlow(int src, int des) { int aug = 0; int sumflow = 0; while ((aug = BFS(src, des)) != -1) { int k = des; //利用前驱寻找路径 while (k != src) { int last = pre[k]; capacity[last][k] -= aug; capacity[k][last] += aug; k = last; } sumflow += aug; } return sumflow; } struct node { string in, out; int cap; }; int checkin(string & a, string& b) { int sz = a.size(); bool judge = 1; for (int i = 0; i < sz; i++) { if (a[i] == '2' || b[i] == '2') { continue; } else if (a[i] != b[i]) { judge = 0; break; } } if (1 == judge) return 1; return 0; } int cur[N]; //后继 int dis[N]; //距离 int gap[N]; //层结点数(用于间隙优化) int SAP(int s, int t) //源点、汇点、结点数 { CLR(gap, 0); CLR(cur, 0); CLR(dis, 0); int u = pre[s] = s, maxflow = 0, aug = INT_MAX; int v; gap[0] = n; while (dis[s] < n) { bool flag = false; for (v = cur[u]; v <= n; ++v) //寻找允许弧 { if (capacity[u][v] > 0 && dis[u] == dis[v] + 1) { flag = true; break; } } if (flag) //找到允许弧 { pre[v] = u; cur[u] = v; aug = min(aug, capacity[u][v]); u = v; if (v == t) //找到完整增广路 { maxflow += aug; for (v = t; v != s; v = pre[v]) //更新残留网络 { capacity[pre[v]][v] -= aug; //正向边 capacity[v][pre[v]] += aug; //反向边 } aug = INT_MAX; u = s; //重新从源点寻找 } } else //找不到允许弧 { int mindis = n; for (v = 1; v <= n; ++v) //重新标号 { if (capacity[u][v] && mindis > dis[v]) { cur[u] = v; mindis = dis[v]; } } if (--gap[dis[u]] == 0) //更新断层 + 判断是否断层(间隙优化) break; gap[dis[u] = mindis + 1]++; //更新断层 u = pre[u]; //当前弧优化 } } return maxflow; } inline void addedge(int x, int y, int c) { // add an arc(x -> y, c); vertex: 0 ~ n-1; capacity[x][y] = c; } int main() { int t, np, nc, m, power, id, u, v, cap; char tmp; while (cin >> t) { scanf("%d%d%d", &np, &nc, &m); int curn = t + 2; n = curn; memset(capacity, 0, sizeof(capacity)); for (int i = 0; i < m; i++) { scanf(" (%d,%d)%d ", &u, &v, &cap); if (u == v) { continue; } else { u++; v++; addedge(u, v, cap); } } for (int i = 0; i < np; i++) { scanf(" (%d)%d ", &id, &power); addedge(0, id + 1, power); } for (int i = 0; i < nc; i++) { int power, id; scanf(" (%d)%d ", &id, &power); addedge(id + 1, curn - 1, power); } int sum = MaxFlow(0, curn - 1); //int sum = SAP( 0, curn - 1); cout << sum << endl; } return 0; }