hdu 3549 网络流模板(dinic + ISAP)
2014-10-03 00:43
435 查看
就是用来检测模板的
一直发现最大流模板放在其他地方,把它存过来
dinic:
ISAP:
一直发现最大流模板放在其他地方,把它存过来
dinic:
#include<queue> #include<iostream> #include<string> #include<cstring> #include<vector> #include<iomanip> #include<stack> #include<cstdio> #include<algorithm> #include<cmath> #include<map> #include<list> using namespace std; const int INF=1e9; #define rep(i,n) for(int i=1;i<=n;i++) const double eps=1e-6; const int maxn = 16; //const int INF=1e9; struct Edge{ int from,to,cap,flow; Edge(int f=0,int t=0,int c=0,int fl=0):from(f),to(t),cap(c),flow(fl){} }; struct Dinic{ int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int cur[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)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS(){ memset(vis,0,sizeof(vis)); queue<int> q; q.push(s); d[s] = 0; vis[s] = 1; while(!q.empty()){ int x = q.front(); q.pop(); for(int i = 0;i < (int)G[x].size(); i++){ Edge &e = edges[G[x][i]]; if(!vis[e.to] && e.cap > e.flow){ vis[e.to] = 1; d[e.to] = d[x] + 1; q.push(e.to); } } } return vis[t]; } int DFS(int x,int a){ if(x==t || a==0) return a; int flow = 0,f; for(int &i = cur[x];i < (int)G[x].size(); i++){ Edge& e = edges[G[x][i]]; if(d[x]+1 == d[e.to] && (f = DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a==0) break; } } return flow; } int maxflow(int s,int t){ this->s = s; this->t = t; int flow = 0; while(BFS()){ memset(cur,0,sizeof(cur)); flow += DFS(s,INF); } return flow; } }; int main() { int T,N,M,x,y,c; cin>>T; int t=1; while(T--){ Dinic di; cin>>N>>M; while(M--){ scanf("%d%d%d",&x,&y,&c); di.AddEdge(x,y,c); } printf("Case %d: %d\n",t++,di.maxflow(1,N)); } return 0; }
ISAP:
#include <iostream> #include <algorithm> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <functional> #include <sstream> #include <iomanip> #include <cmath> #include <cstdlib> #include <ctime> #pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; //typedef pair<int,int> pii; #define INF 1e9 #define MAXN 10000 #define MAXM 100 const int maxn = 20; const int mod = 1000003; #define eps 1e-6 #define pi 3.1415926535897932384626433 #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define scan(n) scanf("%d",&n) #define scan2(n,m) scanf("%d%d",&n,&m) #define scans(s) scanf("%s",s); #define ini(a) memset(a,0,sizeof(a)) #define FILL(a,n) fill(a,a+maxn,n) #define out(n) printf("%d\n",n) //ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b);} #define mk(n,m) make_pair(n,m) using namespace std; struct Edge{ int from,to,cap,flow; Edge(int f = 0, int t = 0, int c = 0, int fl = 0):from(f),to(t),cap(c),flow(fl){} }; int n,m; vector<int> G[maxn]; vector<Edge> edges; bool vis[maxn]; int d[maxn]; //残量网络中从节点i到汇点t的距离 int cur[maxn]; //当前弧下标 int p[maxn]; //可增广路上的上一条弧 int num[maxn]; //距离标号计数 void init(int n) { edges.clear(); rep(i,n+3) G[i].clear(); FILL(d,n+1); } void add(int from,int to,int cap){ edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); int p = edges.size(); G[from].push_back(p - 2); G[to].push_back(p - 1); } bool bfs(int s,int t) { memset(vis, 0, sizeof(vis)); queue<int> q; q.push(t); vis[t] = 1; d[t] = 0; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]^1]; //这条弧的反弧 if (!vis[e.from] && e.cap > e.flow) { vis[e.from] = true; d[e.from] = d[u] + 1; q.push(e.from); } } } return vis[s]; } // 增广 int augment(int s,int t) { int u = t, df = INF; // 从汇点到源点通过 p 追踪增广路径, df 为一路上最小的残量 while (u != s) { Edge &e = edges[p[u]]; df = min(df, e.cap - e.flow); u = edges[p[u]].from; } u = t; // 从汇点到源点更新流量 while (u != s) { edges[p[u]].flow += df; edges[p[u]^1].flow -= df; u = edges[p[u]].from; } return df; } int maxflow(int s,int t) { int flow = 0; bfs(s,t); memset(num, 0, sizeof(num)); for (int i = 0; i < n; i++) num[d[i]]++; int u = s; memset(cur, 0, sizeof(cur)); while (d[s] < n) { if (u == t) { flow += augment(s,t); u = s; } bool advanced = false; for (int i = cur[u]; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if (e.cap > e.flow && d[u] == d[e.to] + 1) { advanced = true; p[e.to] = G[u][i]; cur[u] = i; u = e.to; break; } } if (!advanced) { // retreat int m = n - 1; for (int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if (e.cap > e.flow) m = min(m, d[e.to]); } if (--num[d[u]] == 0) break; // gap 优化 num[d[u] = m+1]++; cur[u] = 0; if (u != s) u = edges[p[u]].from; } } return flow; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif int T; cin>>T; int cas = 1; while(T--) { scan2(n,m); init(n); int u,v,c; rep(i,m) { scanf("%d%d%d",&u,&v,&c); add(u,v,c); } printf("Case %d: %d\n",cas++,maxflow(1,n)); } return 0; }
相关文章推荐
- HDU 3549 适合网络流入门(内含sap模板和Dinic模板)Flow Problem
- HDU 3549 Flow Problem 网络最大流问题 EK、Dinic、ISAP三种算法
- HDU 1523 Drainage Ditches (网络流/dinic/模板)
- 【网络流#1】hdu 3549 - 最大流模板题
- HDU 1569 网络流dinic 模板
- hdu 1532 POJ 1273 Drainage Ditches 和hdu 3549 Flow Problem 网络流入门(EK和dinic)
- hdu 1532 Drainage Ditches(最大流 三种模板:EK、Dinic、isap)
- HDU 3549 Flow Problem - 更新dinic模板..整成结构体...
- HDU 1532 Drainage Ditches 网络流模板题(Dinic)
- hdu 3549 网络流 模板题
- HDU 4280 网络流(ISAP || Dinic)
- HDU 3549 Flow Problem (dinic模版 && isap模版)
- hdu 3549 Flow Problem(简单网络流Dinic)
- 【网络流第三弹】HDU 3549——Flow Problem(dinic解法)
- HDU 3549 Flow Problem 网络流 ISAP
- hdu 1532 Drainage Ditches(网络流dinic模板)
- HDU 3549 Flow Problem(网络流之最大流模板题)
- hdu 3549 Flow Problem(最大流EK算法模板)
- 最大流模板(Dinic, ISAP)
- Flow Problem hdu 3549 网络流模板题目