看代码是学习算法最好的方法之一: #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define init(a,what) memset(a,what,sizeof(a)) #define read freopen("zx.in","r",stdin) #define write freopen("zx.out","w",stdout) const int INF=0x3f3f3f3f; const int MAXN=1000+10; int nnum,mnum,maxn,maxflow,mincost; int fa[MAXN],dist[MAXN],cost[MAXN][MAXN],flow[MAXN][MAXN]; bool vis[MAXN]; void spfa(int s,int e)//先找出最短路 { queue<int>q; init(vis,false); while(!q.empty()) q.pop(); for(int i=1;i<=nnum;i++) dist[i]=(i==s ? 0 : INF); q.push(s); while(!q.empty()) { int cur=q.front(); q.pop(); vis[cur]=false; for(int i=1;i<=nnum;i++) { if(flow[cur][i] && dist[i]>dist[cur]+cost[cur][i]) { dist[i]=dist[cur]+cost[cur][i]; fa[i]=cur;//这里记录路径 if(!vis[i]) { vis[i]=true, q.push(i); } } } } //printf("cost: %d/n",dist[e]);该最短路下的总费用 } void MIN_maxflow(int s,int e)//找出上个最短路下的最大流 { maxn=INF; for(int x=e;x!=s;x=fa[x]) if(maxn>flow[fa[x]][x]) maxn=flow[fa[x]][x]; //printf("flow: %d/n",maxn);该最短路下的增广量 for(int x=e;x!=s;x=fa[x]) { flow[fa[x]][x]-=maxn;//更新流量 flow[x][fa[x]]+=maxn; } } int main() { read, write; while(scanf("%d%d",&nnum,&mnum)!=EOF) { init(flow,0);//这样标记便于后面的判断 init(cost,0); for(int i=0;i<mnum;i++) { int a,b,cap,costt; scanf("%d%d%d%d",&a,&b,&cap,&costt); flow[a][b]+=cap, cost[a][b]=costt, cost[b][a]=-costt; } int start=1, end=nnum; maxflow=mincost=0; while(1) { spfa(start,end); if(dist[end]==INF) break; MIN_maxflow(start,end); maxflow+=maxn; mincost+=dist[end]*maxn; } printf("%d %d/n",mincost,maxflow); } return 0; }