费用流&网络流模版

费用流模版:

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<queue>

 4 using namespace std;

 5 

 6 const int Maxm=100000;//最大边数 

 7 const int Maxn=1000;//最大点数 

 8 struct Edge{

 9     Edge(){};

10     Edge(int a,int b,int c,int d,int e){

11         u=a;

12         v=b; 

13         f=c;

14         w=d;

15         nxt=e;

16     }

17     int u,v,f,w,nxt;//U当前点 V来自点 F最大流量 W费用 NXT下一个点 

18 };

19 int cnt=1;//边计数

20 int inf=2147483647;//无限大 

21 int g[Maxn+10];//点的边集的开始序号 

22 Edge e[Maxm+10];//边集 

23 int dist[Maxn+10];//费用 

24 int src,sink;//源点与汇点 

25 queue<int> que;//宽搜队列 

26 bool inque[Maxn+10];//宽搜判断标志 

27 int from[Maxn+10];//来源->用于计算费用 

28 int ans=0;//存储最小费用 

29 

30 inline int remin(int a,int b){

31     return a<b?a:b;

32 }

33 

34 inline void insert(int u,int v,int f,int w){

35     cnt++;

36     e[cnt]=Edge(u,v,f,w,g[u]);

37     g[u]=cnt;//增加一个边 

38 } 

39 

40 inline void addEdge(int u,int v,int f,int w){

41     insert(u,v,f,w);//插入正边 

42     insert(v,u,0,-w);//插入反边 

43 }

44 

45 inline bool spfa(){

46     while (!que.empty()) que.pop();//清空队列 

47     for (int i=0;i<=sink;i++) dist[i]=inf;//清最大值

48     que.push(src);

49     inque[src]=true;

50     dist[src]=0;//加入源点

51     //标准SPFA计算最短路 流量作为通行标准,费用作为路径长度 

52     while(!que.empty()){

53         int now=que.front();

54         que.pop();

55         for (int i=g[now];i;i=e[i].nxt){

56             if (e[i].f!=0 && dist[e[i].v]>dist[now]+e[i].w){

57                 dist[e[i].v]=dist[now]+e[i].w;

58                 from[e[i].v]=i;

59                 if (inque[e[i].v]==false){

60                     inque[e[i].v]=true;

61                     que.push(e[i].v);

62                 }

63             }

64         }

65         inque[now]=false;

66     } 

67     if (dist[sink]==inf) return false;//无法在增广 

68     return true;

69 }

70 

71 inline void calcAns(){

72     int minflow=inf;

73     for (int i=from[sink];i;i=from[e[i].u]) minflow=remin(minflow,e[i].f);//寻找整条路经的流量 

74     for (int i=from[sink];i;i=from[e[i].u]) {

75         e[i].f-=minflow;//正边减流量 

76         e[i^1].f+=minflow;//反边加流量 

77         ans+=e[i].w*minflow;//计算费用 

78     }

79 }

80 

81 inline void minCostFlow(){

82     while(spfa())calcAns();

83 }

84 

85 int main(){

86     minCostFlow();

87     return 0;

88 }

 

网络流模版:

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<queue>

 4 using namespace std;

 5 

 6 const int Maxm=100000;//最大边数 

 7 const int Maxn=1000;//最大点数 

 8 struct Edge{

 9     Edge(){};

10     Edge(int a,int b,int c,int d,int e){

11         u=a;

12         v=b; 

13         f=c;

14         w=d;

15         nxt=e;

16     }

17     int u,v,f,w,nxt;//U当前点 V来自点 F最大流量 W费用 NXT下一个点 

18 };

19 int cnt=1;//边计数

20 int inf=2147483647;//无限大 

21 int g[Maxn+10];//点的边集的开始序号 

22 Edge e[Maxm+10];//边集 

23 int dist[Maxn+10];//费用 

24 int src,sink;//源点与汇点 

25 queue<int> que;//宽搜队列 

26 bool inque[Maxn+10];//宽搜判断标志 

27 int from[Maxn+10];//来源->用于计算费用 

28 int ans=0;//存储最小费用 

29 

30 inline int remin(int a,int b){

31     return a<b?a:b;

32 }

33 

34 inline void insert(int u,int v,int f,int w){

35     cnt++;

36     e[cnt]=Edge(u,v,f,w,g[u]);

37     g[u]=cnt;//增加一个边 

38 } 

39 

40 inline void addEdge(int u,int v,int f,int w){

41     insert(u,v,f,w);//插入正边 

42     insert(v,u,0,-w);//插入反边 

43 }

44 

45 inline bool spfa(){

46     while (!que.empty()) que.pop();//清空队列 

47     for (int i=0;i<=sink;i++) dist[i]=inf;//清最大值

48     que.push(src);

49     inque[src]=true;

50     dist[src]=0;//加入源点

51     //标准SPFA计算最短路 流量作为通行标准,费用作为路径长度 

52     while(!que.empty()){

53         int now=que.front();

54         que.pop();

55         for (int i=g[now];i;i=e[i].nxt){

56             if (e[i].f!=0 && dist[e[i].v]>dist[now]+e[i].w){

57                 dist[e[i].v]=dist[now]+e[i].w;

58                 from[e[i].v]=i;

59                 if (inque[e[i].v]==false){

60                     inque[e[i].v]=true;

61                     que.push(e[i].v);

62                 }

63             }

64         }

65         inque[now]=false;

66     } 

67     if (dist[sink]==inf) return false;//无法在增广 

68     return true;

69 }

70 

71 inline void calcAns(){

72     int minflow=inf;

73     for (int i=from[sink];i;i=from[e[i].u]) minflow=remin(minflow,e[i].f);//寻找整条路经的流量 

74     for (int i=from[sink];i;i=from[e[i].u]) {

75         e[i].f-=minflow;//正边减流量 

76         e[i^1].f+=minflow;//反边加流量 

77         ans+=e[i].w*minflow;//计算费用 

78     }

79 }

80 

81 inline void minCostFlow(){

82     while(spfa())calcAns();

83 }

84 

85 int main(){

86     minCostFlow();

87     return 0;

88 }

 

你可能感兴趣的:(网络流)