uva11082 最大流和網絡流建模

主要是建模想不到,下面兩篇講的不錯。

http://www.cnblogs.com/xcw0754/p/4646140.html

http://www.cnblogs.com/AOQNRMGYXLMV/p/4280727.html

就是將矩陣的行看成一個水管,列看成一個水管,矩陣的值a[i][j]看成第i行流到第j列的流量。第i行的和就是該行流向所有列的流量之和。

#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 = 100;
const int INF = 0x1fffffff;
struct Edge{
  int from,to,cap;
  Edge (int a1=0,int b1=0,int c1=0):from(a1),to(b1),cap(c1) {}
};
/**********************************************************/
int r,c,s,t,sum;
int rr[NN_MAX],cc[NN_MAX];
int cap[NN_MAX][NN_MAX],flow[NN_MAX][NN_MAX],a[NN_MAX],p[NN_MAX];
/**********************************************************/
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 InitCap ();
void EK ();
/**********************************************************/
int main()
{
  if (READ_FILE) freopen ("in.txt","r",stdin);
  int tt;
  scanf ("%d",&tt);
  for (int i=1;i<=tt;i++)
  {
	scanf ("%d%d",&r,&c);
	rr[0]=cc[0]=0;
	for (int j=1;j<=r;j++)
	  scanf ("%d",&rr[j]);
	for (int j=r;j>=1;j--)
	  rr[j]-=rr[j-1];
	for (int j=1;j<=c;j++)
	  scanf ("%d",&cc[j]);
	for (int j=c;j>=1;j--)
	  cc[j]-=cc[j-1];
	printf ("Matrix %d\n",i);
	InitCap ();
	EK ();
	if (i!=tt) printf ("\n");
  }
  return 0;
}
void InitCap ()
{
  memset (cap,0,sizeof (cap));
  memset (flow,0,sizeof (flow));
  s=0,t=r+c+1;
  for (int i=1;i<=r;i++)
	cap[s][i]=rr[i]-c;
  for (int i=r+1;i<=r+c;i++)
	cap[i][t]=cc[i-r]-r;
  for (int i=1;i<=r;i++)
	for (int j=r+1;j<=r+c;j++)
	  cap[i][j]=19;
  if (OJ_PRINT)
	for (int i=0;i<=r+c+1;i++)
	  for (int j=0;j<=r+c+1;j++)
		if (cap[i][j])
		  printf ("%d %d %d\n",i,j,cap[i][j]);
}
void EK ()
{
  queue<int>qee;
  sum=0;
  while (1)
  {
	memset (a,0,sizeof(a));a[s]=INF;
	qee.push (s);
	while (!qee.empty ())
	{
	  int x=qee.front ();qee.pop ();
	  for (int y=0;y<=r+c+1;y++){
		if (!a[y] && cap[x][y]>flow[x][y]){
		  p[y]=x;
		  qee.push (y);
		  a[y]=min_2 (a[x],cap[x][y]-flow[x][y]);
		}
	  }
	}
	if (a[t]==0) break;
	for (int i=t;i!=s;i=p[i]){
	  flow[p[i]][i]+=a[t];
	  flow[i][p[i]]-=a[t];
	}
  }
  for (int i=1;i<=r;i++)
	for (int j=r+1;j<=r+c;j++){
	  printf ("%d",flow[i][j]+1);
	  j==r+c?printf ("\n"):printf (" ");
	} 
}

發佈了90 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章