题目地址:点击打开链接
思路:网络流入门题,第一次写经验不够,应该把起点和终点单独列出来,这样模板每次只需要改进一部分内容即可
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
#include <queue>
using namespace std;
int map1[20][20],pre[20],vis[20],n;
bool bfs()
{
int cur,i;
queue<int> q;
memset(vis,0,sizeof(vis));
memset(pre,0,sizeof(pre));
vis[1] = 1;//这里写的没有一般性,还得每次改,不好
pre[1] = 0;
q.push(1);
while(!q.empty())
{
cur = q.front();
q.pop();
if(cur == n)
return true;
for(i=1; i<=n; i++)
{
if(!vis[i] && map1[cur][i])
{
vis[i] = 1;
pre[i] = cur;
q.push(i);
}
}
}
return false;
}
int max_flow()
{
int ans = 0,min1,i;
while(1)
{
if(!bfs())//没有增广路径就退出
return ans;
min1 = INT_MAX;
i = n;
while(pre[i])
{
min1 = min(min1,map1[pre[i]][i]);//z找出每次的最小流
i = pre[i];
}
for(i=n; i!=1; i=pre[i])
{
map1[pre[i]][i] -= min1;//正向减流
map1[i][pre[i]] += min1;//反向加流
}
ans += min1;
}
}
int main()
{
int t,m,i,j,a,b,c;
scanf("%d",&t);
for(i=1; i<=t; i++)
{
memset(map1,0,sizeof(map1));
scanf("%d%d",&n,&m);
for(j=0; j<m; j++)
{
scanf("%d%d%d",&a,&b,&c);
map1[a][b] += c;//因为2点之间可能有多条边所以是加,不是直接赋值
}
printf("Case %d: %d\n",i,max_flow());
}
return 0;
}