您的位置:首页 > 编程语言 > C语言/C++

uva820 最大流模板题

2015-08-03 10:02 387 查看
注意以下输出格式,还有就是有重边。

这是邻接表的做法:

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<sstream>
#define LL long long
#define OJ_PRINT 0
#define READ_FILE 0
using namespace std;
const int NN_MAX = 110;
const int MM_MAX = NN_MAX*NN_MAX;
const int INF = 0x1fffffff;
struct Edge{
int from,to,cap,flow;
Edge (int a1,int a2,int a3,int a4):from (a1),to (a2),cap (a3),flow (a4){}
Edge (){}
}theEdge[MM_MAX*4];
/**********************************************************/
int n,m,s,t;
vector<int>G[NN_MAX];
int a[NN_MAX],p[NN_MAX];
int flow=0;
/**********************************************************/
int min_2 (int x,int y) {return x<y?x:y;}
int max_2 (int x,int y) {return x>y?x:y;}
void EK ();
/**********************************************************/
int main()
{
if (READ_FILE) freopen ("in.txt","r",stdin);
int tt=1;
while (scanf ("%d",&n) && n)
{
scanf ("%d %d %d",&s,&t,&m);
for (int i=0;i<=n;i++)
G[i].clear ();
int a1,a2,a3;
int lenEdge=0;
for (int i=0;i<m;i++){
scanf ("%d%d%d",&a1,&a2,&a3);
theEdge[lenEdge++]=Edge (a1,a2,a3,0); G[a1].push_back (lenEdge-1);
theEdge[lenEdge++]=Edge (a2,a1,0,0); G[a2].push_back (lenEdge-1);
theEdge[lenEdge++]=Edge (a2,a1,a3,0); G[a2].push_back (lenEdge-1);
theEdge[lenEdge++]=Edge (a1,a2,0,0); G[a1].push_back (lenEdge-1);
}
flow=0;
EK ();
//if (tt>1) printf ("\n");
printf ("Network %d\nThe bandwidth is %d.\n\n",tt++,flow);

}
return 0;
}
void EK ()
{
while (1)
{
memset (a,0,sizeof (a));
queue<int>qee; qee.push (s);
a[s]=INF;
while (!qee.empty ())
{
int x=qee.front (); qee.pop ();
for (int i=0;i<G[x].size ();i++){
Edge& e=theEdge[G[x][i]];
if (!a[e.to] && e.cap>e.flow){
p[e.to]=G[x][i];
a[e.to]=min_2 (a[x],e.cap-e.flow);
qee.push (e.to);
}
}
//if (a[t]) break;
}
if (a[t]==0) break;
flow+=a[t];
for (int i=t;i!=s;i=theEdge[p[i]].from){
theEdge[p[i]].flow+=a[t];
theEdge[p[i]^1].flow-=a[t];
}
}
}

这是邻接矩阵的做法:

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<sstream>
#define LL long long
#define OJ_PRINT 0
#define READ_FILE 0
using namespace std;
const int NN_MAX = 110;
const int INF = 0x1fffffff;
/**********************************************************/
int n,m,s,t;
int a[NN_MAX],p[NN_MAX],cap[NN_MAX][NN_MAX],flow[NN_MAX][NN_MAX];
int maxflow=0;
/**********************************************************/
int min_2 (int x,int y) {return x<y?x:y;}
int max_2 (int x,int y) {return x>y?x:y;}
void EK ();
/**********************************************************/
int main()
{
if (READ_FILE) freopen ("in.txt","r",stdin);
int tt=1;
while (scanf ("%d",&n) && n)
{
scanf ("%d %d %d",&s,&t,&m);
int a1,a2,a3;
int lenEdge=0;
memset (cap,0,sizeof (cap));
memset (flow,0,sizeof (flow));
for (int i=0;i<m;i++){
scanf ("%d%d%d",&a1,&a2,&a3);
cap[a1][a2]+=a3;
cap[a2][a1]=cap[a1][a2];
}
maxflow=0;
EK ();
printf ("Network %d\nThe bandwidth is %d.\n\n",tt++,maxflow);

}
return 0;
}
void EK ()
{
while (1)
{
queue<int>qee;
memset (a,0,sizeof (a)); a[s]=INF;
qee.push (s);
while (!qee.empty ())
{
int x=qee.front (); qee.pop ();
for (int y=1;y<=n;y++){
if (!a[y] && cap[x][y]>flow[x][y]){
a[y]=min_2 (a[x],cap[x][y]-flow[x][y]);
p[y]=x;
qee.push (y);
}
}
}
if (a[t]==0) break;
maxflow+=a[t];
for (int i=t;i!=s;i=p[i]){
flow[p[i]][i]+=a[t];
flow[i][p[i]]-=a[t];
}
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息