网络流(模板)
Dicnic算法(最大流/最小割问题)
1 ///网络流模板 2 /** 3 * 题意:n个点,m条有向边,s点为源点,t点为汇点,然后是m条边的u,v,w;求s点到t点的最大流 4 */ 5 #include<bits/stdc++.h> 6 using namespace std; 7 #define ll long long 8 const int maxn = 100005; 9 const int maxm = 2000005; 10 const int inf = 0x3f3f3f3f; 11 struct DINIC 12 { 13 struct node 14 { 15 int u,v,w,next; 16 }edge[maxm]; 17 int deep[maxn],dl[maxm],fir[maxm]; 18 int cnt,aim; 19 void init() 20 { 21 memset(fir,-1,sizeof fir); 22 cnt=0; 23 } 24 void add(int u,int v,int w) 25 { 26 edge[cnt].u=u,edge[cnt].v=v,edge[cnt].w=w; 27 edge[cnt].next=fir[u]; 28 fir[u]=cnt++; 29 edge[cnt].u=v,edge[cnt].v=u,edge[cnt].w=0; 30 edge[cnt].next=fir[v]; 31 fir[v]=cnt++; 32 } 33 bool bfs(int S,int T) 34 { 35 memset(deep,0,sizeof deep); 36 deep[S]=1; 37 dl[1]=S; 38 int head=0,tail=1; 39 while(head!=tail) 40 { 41 int v=dl[++head]; 42 for(int u=fir[v]; ~u; u=edge[u].next) 43 { 44 if(edge[u].w&&!deep[edge[u].v]) 45 { 46 deep[edge[u].v]=deep[v]+1; 47 dl[++tail]=edge[u].v; 48 } 49 } 50 } 51 return deep[T]; 52 } 53 int dfs(int now,int fl) 54 { 55 if(now==aim) 56 return fl; 57 int f=0; 58 for(int u=fir[now]; ~u&&fl; u=edge[u].next) 59 { 60 if(edge[u].w&&deep[edge[u].v]==deep[now]+1) 61 { 62 int x=dfs(edge[u].v,min(fl,edge[u].w)); 63 edge[u].w-=x; 64 edge[u^1].w += x; 65 fl-=x; 66 f += x; 67 } 68 } 69 if(!f) 70 deep[now]=-2; 71 return f; 72 } int maxflow(int S,int T) 73 { 74 aim= T; 75 int ans=0; 76 while(bfs(S, T)) 77 ans += dfs(S, inf); 78 return ans; 79 } 80 } dinic; 81 int main() 82 { 83 //n个点,m条边,求S到T的最大流/最小割(dinic算法) 84 int n,m; 85 while(~scanf("%d%d",&n,&m)) 86 { 87 int S,T; 88 scanf("%d%d",&S,&T); 89 dinic.init();///初始化 90 for(int i=1; i<=m; i++) 91 { 92 int u,v,w; 93 scanf("%d%d%d",&u,&v,&w); 94 dinic.add(u,v,w); 95 } 96 printf("%d\n",dinic.maxflow(S,T)); 97 } 98 return 0; 99 }
MCMF算法(最小费用流)
1 ///最小费用最大流 2 /** 3 *题意:n个点,m条有向边,s点为起点,t点为汇点,然后输入每条边的u,v,w(边权),f(花费),求其网络最大流以及最大流时的最小费用 4 */ 5 #include<bits/stdc++.h> 6 #define max(x,y) ((x) > (y) ? (x) : (y)) 7 #define min(x,y) ((x)<(y)?(x):(y)) 8 #define lowbit(x) ((x)&(-(x))) 9 #define FAST ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 10 #define memset0(arr) memset(arr,0,sizeof(arr)) 11 #define il inline 12 using namespace std; 13 typedef long long ll; 14 typedef unsigned long long ull; 15 typedef pair<int,int>pii; 16 const int maxn= 1e6; 17 const int INF=0x7fffffff; 18 const int mod=1e9+7; 19 const double eps =1e-7; 20 const double Pi= acos(-1.0); 21 il int read_int() 22 { 23 char c; 24 int ret=0,sgn=1; 25 do 26 { 27 c=getchar(); 28 } 29 while((c<'0'||c>'9')&&c!='-'); 30 if(c=='-') 31 sgn=-1; 32 else 33 ret=c-'0'; 34 while((c=getchar())>='0'&&c<='9') 35 ret=ret*10+(c-'0'); 36 return sgn*ret; 37 } 38 il ll read_ll() 39 { 40 char c; 41 ll ret=0,sgn=1; 42 do 43 { 44 c=getchar(); 45 } 46 while((c<'0'||c>'9')&&c!='-'); 47 if(c=='-') 48 sgn= -1; 49 else 50 ret=c-'0'; 51 while((c=getchar())>='0'&&c<='9') 52 ret=ret*10+(c-'0'); 53 return sgn * ret; 54 } 55 il ll quick_pow(ll base,ll index) 56 { 57 ll res=1; 58 while(index) 59 { 60 if(index&1) 61 res=res*base%mod; 62 base=base*base%mod; 63 index >>= 1; 64 } 65 return res; 66 } 67 struct edge 68 { 69 int to,capacity,cost,rev; 70 edge() {} 71 edge(int to,int _capacity,int _cost,int _rev):to(to),capacity(_capacity),cost(_cost),rev(_rev) {} 72 }; 73 struct Min_Cost_Max_Flow 74 { 75 int V,H[maxn+5],dis[maxn+5],PreV[maxn+5],PreE[maxn+5]; 76 vector<edge>G[maxn+5]; 77 void Init(int n) 78 { 79 V = n; 80 for(int i=0; i<=V; ++i) 81 G[i].clear(); 82 } 83 void Add_Edge(int from,int to,int cap, int cost) 84 { 85 G[from].push_back(edge(to,cap,cost,G[to].size())); 86 G[to].push_back(edge(from,0,-cost,G[from].size()-1)); 87 } 88 int Min_cost_max_flow(int s, int t, int f, int& flow) 89 { 90 int res=0; 91 fill(H,H+1+V,0); 92 while (f) 93 { 94 priority_queue<pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > >q; 95 fill(dis,dis+1+V,INF); 96 dis[s]=0; 97 q.push(pair<int,int>(0,s)); 98 while(!q.empty()) 99 { 100 pair<int,int>now=q.top(); 101 q.pop(); 102 int v=now.second; 103 if(dis[v]<now.first) 104 continue; 105 for (int i=0; i<G[v].size(); ++i) 106 { 107 edge& e=G[v][i]; 108 if(e.capacity>0&&dis[e.to]>dis[v]+e.cost+H[v]-H[e.to]) 109 { 110 dis[e.to]=dis[v]+e.cost+H[v]-H[e.to]; 111 PreV[e.to]=v; 112 PreE[e.to]=i; 113 q.push(pair<int,int>(dis[e.to], e.to)); 114 } 115 } 116 } 117 if(dis[t]==INF) 118 break; 119 for(int i=0; i<=V; ++i) 120 H[i]+= dis[i]; 121 int d = f; 122 for(int v=t; v!=s; v=PreV[v]) 123 d=min(d,G[PreV[v]][PreE[v]].capacity); 124 f-=d; 125 flow+=d; 126 res+=d*H[t]; 127 for(int v=t; v!=s; v=PreV[v]) 128 { 129 edge& e = G[PreV[v]][PreE[v]]; 130 e.capacity -= d; 131 G[v][e.rev].capacity += d; 132 } 133 } 134 return res; 135 } 136 int Max_cost_max_flow(int s,int t,int f,int& flow) 137 { 138 int res=0; 139 fill(H,H+1+V,0); 140 while(f) 141 { 142 priority_queue< pair<int,int> >q; 143 fill(dis,dis+1+V,-INF); 144 dis[s]=0; 145 q.push(pair<int,int>(0,s)); 146 while(!q.empty()) 147 { 148 pair<int,int>now=q.top(); 149 q.pop(); 150 int v= now.second; 151 if(dis[v]>now.first) 152 continue; 153 for(int i=0; i<G[v].size(); ++i) 154 { 155 edge& e=G[v][i]; 156 if(e.capacity>0&&dis[e.to]<dis[v]+e.cost+H[v]-H[e.to]) 157 { 158 dis[e.to]=dis[v]+e.cost+H[v]-H[e.to]; 159 PreV[e.to]=v; 160 PreE[e.to]=i; 161 q.push(pair<int,int>(dis[e.to],e.to)); 162 } 163 } 164 } 165 if(dis[t]==-INF) 166 break; 167 for(int i=0; i<=V; ++i) 168 H[i]+=dis[i]; 169 int d=f; 170 for(int v=t; v!=s; v=PreV[v]) 171 d=min(d,G[PreV[v]][PreE[v]].capacity); 172 f-=d; 173 flow+=d; 174 res+=d*H[t]; 175 for(int v=t; v!=s; v=PreV[v]) 176 { 177 edge& e=G[PreV[v]][PreE[v]]; 178 e.capacity-=d; 179 G[v][e.rev].capacity+=d; 180 } 181 } 182 return res; 183 } 184 }; 185 int n,k,s1,s2,t,flow,arr[maxn+5]; 186 Min_Cost_Max_Flow MCMF; 187 int main() 188 { 189 int n,m,s,t; 190 scanf("%d%d%d%d",&n,&m,&s,&t); 191 MCMF.Init(n); 192 for(int i=1; i<=m; i++) 193 { 194 int u,v,w,c; 195 scanf("%d%d%d%d",&u,&v,&w,&c); 196 MCMF.Add_Edge(u,v,w,c); 197 } 198 flow=0; 199 int ans=MCMF.Min_cost_max_flow(s,t,INF,flow); 200 printf("%d %d\n",flow,ans); 201 return 0; 202 }