POJ 3469 网络流最小割

将两个CPU分别视作源点和汇点

对于那些不在同一个CPU中的模块会产生的代价作为一条双向的容量弧

这里每个模块可以在任意一个CPU中运行,相当于寻找一个割,分割后,在S集合中的模块安装在第一个CPU中

那么在T集合中的模块就是在第二个CPU中,所求的最小割也正是最小耗费

根据最大流=最小割的原理,这里相当于是在求最大流

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 #include <queue>

 5 

 6 using namespace std;

 7 const int N = 20010;

 8 const int INF = 0x3f3f3f3f;

 9 int lev[N],first[N],k;

10 

11 struct Edge{

12     int u , v , cap , flow , next;

13 }e[N*30];

14 

15 void add_edge(int u , int v , int cap)

16 {

17     e[k].u=u , e[k].v = v , e[k].cap=cap , e[k].flow=0 , e[k].next = first[u];

18     first[u]=k++;

19 }

20 //寻找层次网络是否存在

21 bool find_level(int n)

22 {

23     queue<int> q;

24     q.push(0);

25     memset(lev , 0 , sizeof(lev));

26     lev[0]=1;

27     while(!q.empty())

28     {

29         int u=q.front();

30         q.pop();

31         for(int i=first[u] ; i!=-1 ; i=e[i].next){

32             int v = e[i].v;

33             if(!lev[v] && e[i].cap > e[i].flow){

34                 lev[v] = lev[u]+1;

35                 q.push(v);

36             }

37         }

38     }

39     return lev[n+1]>0;

40 }

41 

42 int Dinic(int n , int u , int sum)

43 {

44     int s = sum , t;

45     if(u == n+1) return sum;

46     for(int i=first[u] ; i!=-1 ;i=e[i].next)

47     {

48         int v = e[i].v;

49         if(lev[v] != lev[u]+1 || e[i].cap <= e[i].flow) continue;

50         t = Dinic(n , v , min(sum , e[i].cap - e[i].flow));

51         e[i].flow += t;

52         e[i^1].flow -= t;

53         sum-=t;

54     }

55     return s-sum;

56 }

57 

58 int main()

59 {

60    // freopen("a.in" , "r" , stdin);

61     int n , m , u , v , cap1 , cap2;

62     while(scanf("%d%d" , &n , &m) == 2)

63     {

64         k=0;

65         memset(first , -1 , sizeof(first));

66         for(int i=0 ; i<n ; i++)

67         {

68             scanf("%d%d" , &cap1 , &cap2);

69             //添加双向弧

70             add_edge(0 , i+1 , cap1);

71             add_edge(i+1 , 0 , 0);

72 

73             add_edge(i+1 , n+1 , cap2);

74             add_edge(n+1 , i+1 , 0);

75         }

76         for(int i=0 ; i<m ; i++)

77         {

78             scanf("%d%d%d" , &u , &v , &cap1);

79             add_edge(u , v , cap1);

80             add_edge(v , u , cap1);

81         }

82         int max_flow = 0;

83         while(find_level(n)){

84             max_flow += Dinic(n , 0 , INF);

85         }

86         printf("%d\n" , max_flow);

87     }

88     return 0;

89 }

 

你可能感兴趣的:(poj)