题意:
简单的说下题意(按输入输出来讲,前面的描述一堆的rubbish,还用来误导人),给你n个点,其中有np个是能提供电力的点,nc个是能消费电力的点,剩下的点(n-np-nc)是中转战即不提供电力也不消费电力,点与点之间是有线路存在的,有m条线路,每条线路有最多运载限定。
前4个数据就是有n个点,np个供电点,nc个消费点,m条线路,接来题目先给出的是m条线路的数据,(起点,终点)最多运载量,然后是np个供电点的数据(供电点)最多供电量,接着就是nc个消费点的数据(消费点)最多消费电量。
题目要我们求出给定的图最大能消费的总电量(就是求最大流)
分析:增加一个超级源点,和超级汇点。。把所给的发电站都和超级源点相连,把所给的消耗战都和超级汇点相连
然后需要注意的地方就是输入的地方有点坑,大家注意一下输入的地方就可以了
下面的是我用ISAP做的,正好刚入门网络流,也正好学到ISAP,小试一下QAQ
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
const int max_nodes=4e4;
const int INF=0x3f3f3f3f;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define me(a,b) memset(a,b,sizeof a)
typedef long long ll;
struct node
{
int from,to,capacity,flow;
};
vector<int>G[max_nodes];
vector<node>edges;
vector<int>::iterator it;
int num_nodes;
int source; // 源点
int sink; // 汇点
int p[max_nodes]; // 可增广路上的上一条弧的编号
int num[max_nodes]; // 和 t 的最短距离等于 i 的节点数量
int cur[max_nodes]; // 当前弧下标
int d[max_nodes]; // 残量网络中节点 i 到汇点 t 的最短距离
bool vis[max_nodes];
typedef vector<int>::iterator iterator_t ;
void add(int u,int v,int w){
edges.push_back((node){u,v,w,0});
edges.push_back((node){v,u,0,0});
int k=edges.size();
G[u].push_back(k-2);
G[v].push_back(k-1);
}
void bfs(){
memset(vis,0,sizeof vis);
memset(d,0,sizeof d);
queue<int>q;
q.push(sink);
vis[sink]=1;
d[sink]=0;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<G[u].size();i++){
node e=edges[G[u][i]^1];
if(!vis[e.from]&&e.capacity>e.flow){
vis[e.from]=1;
d[e.from]=d[u]+1;
q.push(e.from);
}
}
}
}
int augment(){
int df=INF,u=sink;
while(u!=source){
node e=edges[p[u]];
df=min(df,e.capacity-e.flow);
u=edges[p[u]].from;
}
u=sink;
while(u!=source){
edges[p[u]].flow+=df;
edges[p[u]^1].flow-=df;
u=edges[p[u]].from;
}
return df;
}
int max_flow(){
int ans=0;
bfs();
memset(num,0,sizeof num);
for(int i=0;i<num_nodes;i++) num[d[i]]++;
int u=source;
memset(p,0,sizeof p);
memset(cur,0,sizeof cur);
while(d[source]<num_nodes){
if(u==sink){
ans+=augment();
u=source;
}
bool flag=0;
for(int i=cur[u];i<G[u].size();i++){
node e=edges[G[u][i]];
if(e.capacity>e.flow&&d[u]==d[e.to]+1){
flag=1;
p[e.to]=G[u][i];
cur[u]=i;
u=e.to;
break;
}
}
if(!flag){
int m=num_nodes-1;
for(int i=0;i<G[u].size();i++){
node e=edges[G[u][i]];
if(e.capacity>e.flow)
m=min(m,d[e.to]);
}
if(--num[d[u]]==0) break;
num[d[u]=m+1]++;
cur[u]=0;
if(u!=source)
u=edges[p[u]].from;
}
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int n,np,nc,m;
int u,v,w;
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
while(m--){
while(getchar()!='(');
scanf("%d,%d)%d",&u,&v,&w);
u++;v++;
add(u,v,w);
}
while(np--){
while(getchar()!='(');
scanf("%d)%d",&u,&w);
u++;
add(0,u,w);
}
while(nc--){
while(getchar()!='(');
scanf("%d)%d",&u,&w);
u++;
add(u,n+1,w);
}
sink=n+1;
num_nodes=n+2;
source=0;
printf("%d\n",max_flow());
for(int i=0;i<=num_nodes;i++)
G[i].clear();
edges.clear();
}
return 0;
}
emmmmm,这个当做模板也是可以的