题意:题意炒鸡坑……有n个电站,有np个发电站,只发电,还有nc个用电站,只用电,剩下的都是中转站,然后有m条电缆,先给出每条电缆能输送的最大电量,再给出每个发电站的最大发电量,最后是每个用电站的最大用电量,求所有用电站最多用点的和。
解法:最大流。题目很裸……只是题意太罗嗦了……建图的时候因为是多源点多汇点,所以设一个超级源一个超级汇,超级源到每个源的边权即为源的最大发电量,超级汇同理。直接在大白上掏了个dinic的模板敲……各种敲错……初始化的范围还没写对各种wa……orz
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
const int maxn = 310;
const int inf = 0x3f3f3f3f;
int n, m, s, t;
vector <int> G[maxn];
bool vis[maxn];
int d[maxn];
struct Edge
{
int from, to, cap, flow;
};
vector <Edge> edges;
void init()
{
for(int i=0; i <= n + 10; i++) G[i].clear();
edges.clear();
}
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);
}
int cur[maxn];
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 < 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 < 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()
{
s = n + 1, t = n + 2;
int flow = 0;
while(bfs())
{
memset(cur, 0, sizeof cur);
flow += dfs(s, inf);
}
return flow;
}
int main()
{
int np, nc, k;
while(~scanf("%d%d%d%d", &n, &np, &nc, &k))
{
init();
while(k--)
{
int a, b, c;
scanf(" (%d,%d)%d", &a, &b, &c);
addEdge(a + 1, b + 1, c);
}
while(np--)
{
int a, b;
scanf(" (%d)%d", &a, &b);
addEdge(n + 1, a + 1, b);
}
while(nc--)
{
int a, b;
scanf(" (%d)%d", &a, &b);
addEdge(a + 1, n + 2, b);
}
printf("%d\n", maxFlow());
}
return 0;
}
原文:http://www.cnblogs.com/Apro/p/4736352.html