将两个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 }

 

 posted on 2015-02-10 15:43  Love风吟  阅读(185)  评论(0编辑  收藏  举报