题意:
有np个发电站nc个用电器,当然还有中转站,不消耗电量。问最多能用多少电。
思路:
标准的网络最大流,s设为101,t设为102,vector模拟邻接链表。
之前一直用Ford-Fulkerson算法写,但是TE,还是用dinic算法吧,重点理解
bfs的作用,其实是提前做了优化,然后在dfs中便省事很多。
更绝的是iter的作用,可以让增广之后的边或者没用用的边跳过。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 105;
const int INF = 0x3f3f3f3f;
struct edge
{
int to,cap,rec;
};
vector<edge> G[MAXN];
bool used[MAXN];
int level[MAXN];
int iter[MAXN];
void add_edge(int from,int to,int c)
{
/*
for(int i = 0;i < G[to].size(); i++) {
if(G[to][i].to == from)
return ;
}
*/
G[from].push_back((edge){to,c,G[to].size()});
G[to].push_back((edge){from,0,G[from].size()-1});
}
void bfs(int s)
{
memset(level,-1,sizeof(level));
queue<int>que;
level[s] = 0;
que.push(s);
while(!que.empty()) {
int v = que.front();que.pop();
for(int i = 0;i < G[v].size(); i++) {
edge &e = G[v][i];
if(e.cap > 0 && level[e.to] < 0) {
level[e.to] = level[v] + 1;
que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f)
{
if(v == t) return f;
used[v] = true;
for(int &i = iter[v];i < G[v].size(); i++) {
edge &e = G[v][i];
if(e.cap > 0 && level[v] < level[e.to]) {
int d = dfs(e.to,t,min(f,e.cap));
if(d > 0) {
e.cap -= d;
G[e.to][e.rec].cap += d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)
{
int flow = 0;
int f;
for( ;; ) {
bfs(s);
if(level[t] < 0) return flow;
memset(iter,0,sizeof(iter));
while( (f = dfs(s,t,INF)) > 0) {
flow += f;
}
}
}
int n,np,nc,m;
int main()
{
//freopen("in.txt","r",stdin);
while(cin>>n>>np>>nc>>m) {
for(int i = 0;i <= 105; i++) {
G[i].clear();
}
char temp;
int s,e,c;
for(int i = 0;i < m; i++) {
cin>>temp>>s>>temp>>e>>temp>>c;
add_edge(s,e,c);
}
for(int i = 0;i < np; i++) {
cin>>temp>>s>>temp>>c;
add_edge(101,s,c);
}
for(int i = 0;i < nc; i++) {
cin>>temp>>s>>temp>>c;
add_edge(s,102,c);
}
printf("%d\n",max_flow(101,102));
}
return 0;
}