BZOJ 2502 上下界网络流

来源:互联网 发布:列主元三角分解法C语言 编辑:程序博客网 时间:2024/06/05 23:54

        首先推荐一篇文章http://wenku.baidu.com/link?url=eFIg-AoMXJLIN3iYZzAHmS61E1_eguZurgyYk6HqhZ8fJQLWoR885UIx8q3ADiQiRU62v8KxDhUys4ibYhEn8zID17Otr3hbtQ4GiU8ro6y

        然后就是裸的最小流

        话说网上很多神奇构图都什么心态,二分+Dinic大法好!

#include <cstdio>#include <vector>#include <queue>#include <cstring>using namespace std;const int MAXN = 1001;const int INF = 10000001;struct Edge{int from,to,cap,flow;};int n,S,T,SS,ST;int dist[MAXN],a[MAXN],cur[MAXN];bool vis[MAXN];vector <Edge> Edges;vector <int> G[MAXN];void AddEdge(int from,int to,int cap){Edges.push_back((Edge){from,to,cap,0});Edges.push_back((Edge){to,from,0,0});int m = Edges.size();G[from].push_back(m-2);G[to].push_back(m-1);}void clear(int mid){for (int i=0;i<Edges.size();i++) Edges[i].flow = 0;Edges[Edges.size()-2].cap = mid;}bool bfs(int s,int t){memset(dist,0,sizeof(dist));queue <int> Q;Q.push(s);dist[s] = 1;while (!Q.empty()){int u = Q.front();Q.pop();for (int i=0;i<G[u].size();i++){Edge e = Edges[G[u][i]];if (e.cap <= e.flow) continue;if (!dist[e.to]){dist[e.to] = dist[u]+1;Q.push(e.to);}}}return dist[t];}int dfs(int u,int a,int t){if (u == t || a <= 0) return a;int flow = 0;for (int &i = cur[u];i<G[u].size();i++){Edge &e = Edges[G[u][i]];if (e.cap > e.flow && dist[e.to] == dist[u]+1){int f = dfs(e.to,min(a,e.cap-e.flow),t);if (f <= 0) continue;e.flow += f;Edges[G[u][i]^1].flow -= f;flow += f;a -= f;if (a == 0) break;}}return flow;}void Dinic(int s,int t){while (bfs(s,t)){memset(cur,0,sizeof(cur));dfs(s,INF,t);}}bool check(){for (int i=0;i<G[SS].size();i++) {Edge e = Edges[G[SS][i]];if (e.cap > e.flow) return false;}return true;}int main(){scanf("%d",&n);S = 0, T = n+1;SS = n+2, ST = n+3;for (int i=1;i<=n;i++){int cnt;scanf("%d",&cnt);for (int j=1;j<=cnt;j++){int x;scanf("%d",&x);AddEdge(i,ST,1);AddEdge(SS,x,1);AddEdge(i,x,INF);vis[x] = true;}if (cnt == 0) AddEdge(i,T,INF);}for (int i=1;i<=n;i++) if (!vis[i]) AddEdge(S,i,INF);AddEdge(T,S,INF);int l = 1, r = 100001;while (l+1 != r){int mid = (l+r)/2;clear(mid);Dinic(SS,ST);if (check()) r = mid;else l = mid;}printf("%d\n",r);return 0;}


0 0