Dual Core CPU
Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Officer of TinySoft Corporation, decided to update their famous product - SWODNIW. The routine consists of N modules, and each of them should run in a certain core. The costs for all the routines to execute on two cores has been estimated. Let's define them as Ai and Bi. Meanwhile, M pairs of modules need to do some data-exchange. If they are running on the same core, then the cost of this action can be ignored. Otherwise, some extra cost are needed. You should arrange wisely to minimize the total cost. Input There are two integers in the first line of input data, N and M (1 ≤ N ≤ 20000, 1 ≤ M ≤ 200000) . Output Output only one integer, the minimum total cost. Sample Input 3 1 1 10 2 10 10 3 2 3 1000 Sample Output 13 Source
POJ Monthly--2007.11.25, Zhou Dong
|
题意 在双核CPU中 有n个模块 每个模块在两个CPU中运行 耗费分别是Ai Bi
同时 m对模块之间需要共享数据 如果这一对模块不在同一个CPU中运行 需要额外的耗费 w
求所有模块运行的最小耗费
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009//根据题目要求进行修改
#define MAXN 20010//根据数据大小进行修改
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl;
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
struct Dinic
{
struct Edge
{
int from,to,cap,flow;
bool operator <(const Edge e) const
{
if(e.from!=from) return from<e.from;
else return to<e.to;
}
Edge() {}
Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow) {}
};
vector<Edge> edges;
vector<int> G[MAXN];
bool vis[MAXN];//BFS使用
int d[MAXN]; //从起点到i的距离
int cur[MAXN]; //当前弧下标
int n,m,s,t,maxflow; //节点数 边数(包括反向弧) 源点编号和弧点编号
void init(int n)
{
this->n=n;
for(int i=0;i<=n;i++)
G[i].clear();
edges.clear();
}
void addedge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool bfs()
{
MEM(vis,0);
MEM(d,-1);
queue<int> q;
q.push(s);
d[s]=maxflow=0;
vis[s]=1;
while(!q.empty())
{
int u=q.front(); q.pop();
int sz=G[u].size();
for(int i=0;i<sz;i++)
{
Edge e=edges[G[u][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
d[e.to]=d[u]+1;
vis[e.to]=1;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int u,int a)
{
if(u==t||a==0) return a;
int sz=G[u].size();
int flow=0,f;
for(int &i=cur[u];i<sz;i++)
{
Edge &e=edges[G[u][i]];
if(d[u]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[u][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
}
int Maxflow(int s,int t)
{
this->s=s; this->t=t;
int flow=0;
while(bfs())
{
MEM(cur,0);
flow+=dfs(s,INF);
}
return flow;
}
}Dic;
int main()
{
// fread;
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int s=0,t=n+1;
Dic.init(t);
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
Dic.addedge(s,i,a);
Dic.addedge(i,t,b);
}
for(int i=0;i<m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Dic.addedge(u,v,w);
Dic.addedge(v,u,w);//建双向边
}
printf("%d\n",Dic.Maxflow(s,t));
}
return 0;
}
每个模块分别与两个CPU之间建边 权值分别为Ai Bi
每对需要共享数据的模块之间建边(双向) 权值为额外的耗费
每个模块都只能在一个CPU中运行
题目即可转化为求已建图的割的最小值
根据最小割最大流定理 求最大流