标签:can put 流量 心得 bsp \n using 复杂 min
题目链接:http://poj.org/problem?id=3436
解题心得:
#include <stdio.h> #include <cstring> #include <stdlib.h> #include <queue> #include <math.h> #include <vector> #include <climits> using namespace std; const int maxn = 1e4+7; const int INF = INT_MAX; int p, n, S, T, level[maxn], iter[maxn]; struct Machine { int in[15]; int out[15]; int p; }m[maxn]; struct Edge { int to, cap, rev, flow; Edge(int To, int Cap, int Rev, int Flow): to(To), cap(Cap), rev(Rev), flow(Flow){} }; vector <Edge> ve[maxn]; void add_edge(int s,int t, int cap) {//建边 ve[s].push_back(Edge(t, cap, ve[t].size(), 0)); ve[t].push_back(Edge(s, 0, ve[s].size()-1, 0)); } void build_edge() {//找出口和入口的关系 for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i == j) continue; bool flag = false; for(int k=1;k<=p;k++) { if(m[j].in[k] != 2 && m[i].out[k] != m[j].in[k]) { flag = true; break; } } if(!flag) add_edge(i+n, j, INF); } add_edge(i, i+n, m[i].p); } } void init() { scanf("%d%d",&p,&n); S = 0, T = 2*n + 1; for(int i=1;i<=n;i++) {//找起始机器和末尾机器 scanf("%d", &m[i].p); bool flag = false; for (int j = 1; j <= p; j++) { scanf("%d", &m[i].in[j]); if (m[i].in[j] == 1) flag = true; } if (!flag) add_edge(S, i, INF); flag = false; for (int j = 1; j <= p; j++) { scanf("%d", &m[i].out[j]); if (m[i].out[j] != 1) flag = true; } if (!flag) add_edge(i+n, T, INF); } build_edge(); } bool bfs() { memset(level, -1, sizeof(level)); level[S] = 0; queue <int> qu; qu.push(S); while(!qu.empty()) { int now = qu.front(); qu.pop(); for(int i=0; i<ve[now].size(); i++) { Edge &e = ve[now][i]; if(e.cap > e.flow && level[e.to] < 0) { level[e.to] = level[now] + 1; qu.push(e.to); } } } return level[T] > 0; } int dfs(int now, int f) { if(now == T) return f; for(int &i=iter[now]; i<ve[now].size(); i++) { Edge &e = ve[now][i]; if(e.cap > e.flow && level[e.to] > level[now]) { int d = dfs(e.to, min(f, e.cap-e.flow)); if(d > 0) { e.flow += d; ve[e.to][e.rev].flow -= d; return d; } } } return 0; } int max_flow() {//Dinic跑最大流 int ans = 0; while(bfs()) { int f = dfs(S, INF); memset(iter, 0, sizeof(iter)); if(f > 0) ans += f; else break; } return ans; } int cnt, path[maxn][5]; void Print_path(int ans) {//把路找出来 cnt = 0; for(int i=n+1;i<=2*n;i++) { for(int j=0;j<ve[i].size();j++) { Edge &e = ve[i][j]; if(e.flow > 0 && e.to <= n) { path[cnt][0] = i - n; path[cnt][1] = e.to; path[cnt][2] = e.flow; cnt++; } } } printf("%d %d\n",ans, cnt); for(int i=0;i<cnt;i++) printf("%d %d %d\n",path[i][0], path[i][1], path[i][2]); } int main() { init(); int ans = max_flow(); Print_path(ans); }
POJ-3436:ACM Computer Factory (Dinic最大流)
标签:can put 流量 心得 bsp \n using 复杂 min
原文地址:https://www.cnblogs.com/GoldenFingers/p/9497667.html