将两个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 }
我还在坚持,我还未达到我所想,梦~~一直在