标签:mat next div time node break res == ret
对城市拆点 城市之间的容量就是 在这个城市设立关卡需要的费用 求最小割 跑一遍最大流
#include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 100005; int n, m;//点数、边数 int sp, tp;//原点、汇点 struct node { int u; int v, next; int cap; }mp[maxn]; int pre[maxn], dis[maxn], cur[maxn];//cur为当前弧优化,dis存储分层图中每个点的层数(即到原点的最短距离),pre建邻接表 int cnt = 0; void init() { //不要忘记初始化 cnt = 0; memset(pre, -1, sizeof(pre)); } void add(int u, int v, int w) { //加边 mp[cnt].u = u; mp[cnt].v = v; mp[cnt].cap = w; mp[cnt].next = pre[u]; pre[u] = cnt++; mp[cnt].u = v; mp[cnt].v = u; mp[cnt].cap = 0; mp[cnt].next = pre[v]; pre[v] = cnt++; } bool bfs() { //建分层图 memset(dis, -1, sizeof(dis)); queue<int>q; while(!q.empty()) q.pop(); q.push(sp); dis[sp] = 0; int u, v; while(!q.empty()) { u = q.front(); q.pop(); for(int i = pre[u]; i != -1; i = mp[i].next) { v = mp[i].v; if(dis[v] == -1 && mp[i].cap > 0) { dis[v] = dis[u] + 1; q.push(v); if(v == tp) break; } } } return dis[tp] != -1; } int dfs(int u, int cap) {//寻找增广路 if(u == tp || cap == 0) return cap; int res = 0, f; for(int i = cur[u]; i != -1; i = mp[i].next) {// int v = mp[i].v; if(dis[v] == dis[u] + 1 && (f = dfs(v, min(cap - res, mp[i].cap))) > 0) { mp[i].cap -= f; mp[i ^ 1].cap += f; res += f; if(res == cap) return cap; } } if(!res) dis[u] = -1; return res; } int dinic() { int ans = 0; while(bfs()) { for(int i = sp; i <= tp; i++) cur[i] = pre[i]; ans += dfs(sp, inf); } return ans; } int main() { int n, m; int t1, t2; while(scanf("%d%d", &n, &m)!=EOF) { init(); sp = 0; tp = 2*n+2; scanf("%d%d", &t1, &t2); add(sp, t1, inf); add(n+t2, tp, inf); for(int i = 1; i <= n; i++) { int t; scanf("%d", &t); add(i, i+n, t); } for(int i = 0; i < m; i++) { int t1, t2; scanf("%d%d", &t1, &t2); add(n+t1, t2, inf); add(n+t2, t1, inf); } int f = dinic(); printf("%d\n", f); } return 0; }
标签:mat next div time node break res == ret
原文地址:https://www.cnblogs.com/16-CHQ/p/8969732.html