题目有点难懂,其实是无源无汇最大流。将源点和所有station相连,容量限制为生产量;将所有consumer和汇点相连,容量限制为消耗量。输入控制有点麻烦,通过在scanf()的格式控制串中加空格吃掉输入中多余的空格。 #include <iostream> using namespace std; #define MAXN 105 #define MIN(x,y) (x<y?x:y) #define INF 20005 int map[MAXN][MAXN]; int max_flow(int num,int map[][MAXN],int source,int sink)//参数含义:结点数量 网络 源点 汇点 { int my_queue[MAXN],queue_first,queue_end;//数组做队列 实现BFS搜索路径 int pre[MAXN],min_flow[MAXN];//记录结点的父节点 当前路径中最小的一段的值,也即限制值 int flow[MAXN][MAXN];//记录当前网络中的流 int ans=0;//最终结果 memset(flow,0,sizeof(flow)); while(1)//一直循环,直到不存在增广路径 { queue_first=0;//初始化队列 queue_end=0; my_queue[queue_end++]=source; memset(pre,-1,sizeof(pre)); min_flow[source]=INF; pre[source]=-2;//源点的父节点需特殊标示 while(queue_first<queue_end)//BFS寻找增广路径 { int temp=my_queue[queue_first++];//出队列 for(int i=0;i<num;i++)//由结点temp往外扩展 { if(pre[i]==-1&&flow[temp][i]<map[temp][i])//当结点i还未被探索到,并且还有可用流量 { my_queue[queue_end++]=i;//加入队列 pre[i]=temp;//标示父节点 min_flow[i]=MIN(min_flow[temp],(map[temp][i]-flow[temp][i]));//求得min_flow } } if(pre[sink]!=-1)//sink的父节点不为初始值,说明BFS已经找到了一条路径 { int k=sink; while(pre[k]>=0) { flow[pre[k]][k]+=min_flow[sink];//将新的流量加入flow flow[k][pre[k]]=-flow[pre[k]][k]; k=pre[k]; } break; } } if(pre[sink]==-1) return ans;//不存在增广路径,返回 else ans+=min_flow[sink]; } } int main() { int n,np,nc,m; while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) { memset(map,0,sizeof(map)); int node1,node2,limit; for(int i=0;i<m;i++) { scanf(" (%d,%d)%d",&node1,&node2,&limit); map[node1][node2]=limit; } for(int i=0;i<np;i++)//结点n为源点,和station相连 { scanf(" (%d)%d",&node1,&limit); map[n][node1]=limit; } for(int i=0;i<nc;i++)//结点n+1为汇点,和consumer相连 { scanf(" (%d)%d",&node1,&limit); map[node1][n+1]=limit; } printf("%d/n",max_flow(n+2,map,n,n+1)); } return 0; }