每个module都是一个节点,都有两条边,一条从s练到该节点,一条从该节点连到t,边的容量即为放在对应core上的代价。如果我们把这个module放在coreA上,就等价于隔断s到该节点的那条边,反之,如果放在coreB上,就等价于割掉该节点到t的那条边,如果两个module需要连载一起,不然要付出额外代价的话,我们就可以在这两个module之间也连一条边,如果他们两个一个与s相连,一个与t相连的话,我们就需要把他们两个之间的边也割掉,保证割集成立。因为要求最小代价,即为最小割,所以求最大流即可。
#include<iostream>
#include<math.h>
#include<iomanip>
#include <string>
#include <cstdio>
#include<stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include<vector>
#define INF 0x3f3f3f3f
#define N 20100
#define ll long long
using namespace std;int stop;
#include<iostream>
#include<math.h>
#include<iomanip>
#include <string>
#include <cstdio>
#include<stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include<vector>
#define INF 0x3f3f3f3f
#define N 30000
#define ll long long
using namespace std;
struct Edge{
int from,to,cap,flow;
Edge(int a=0,int b=0,int c=0, int d=0){
from = a,to = b,cap = c,flow = d;
}
};
vector<Edge>edges;
vector<int>G[N];
int n,m,s,t;
void addedge(int from, int to,int cap){
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
int m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool vis[N];
int cur[N],deep[N];
bool bfs(){
memset(vis,0,sizeof(vis));
queue<int>que;
que.push(s);
deep[s] = 0;
vis[s] = 1;
while (!que.empty())
{
int x = que.front();que.pop();
for(int i=0;i<G[x].size();i++){
Edge& e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow){//无视没有残量的弧
vis[e.to] = 1;deep[e.to] = deep[x]+1;
que.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x,int a){
if(x == t || a == 0){
return a;
}
int flow = 0,f;
for(int& i = cur[x];i<G[x].size();i++){
Edge& e = edges[G[x][i]];
if(deep[x]+1 == deep[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow))) > 0){//可以流
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a == 0){
break;
}
}
}
return flow;
}
ll maxflow(){
ll flow = 0;
while (bfs())
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
int main()
{
int i,x,y,z;
while(~scanf("%d%d",&n,&m)){
s = 0;t = n+1;
for(i=1;i<=n;i++){
scanf("%d%d",&x,&y);
addedge(s,i,x);
addedge(i,t,y);
}
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
addedge(y,x,z);
}
printf("%d\n",maxflow());
}
return 0;
}
Dinic代码