POJ 3469 Dual Core CPU

来源:互联网 发布:淘宝开药店的条件 编辑:程序博客网 时间:2024/05/29 18:26

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 asAi 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) .
The next N lines, each contains two integer, Ai and Bi.
In the following M lines, each contains three integers: a, b, w. The meaning is that if module a and module b don't execute on the same core, you should pay extraw dollars for the data-exchange between them.

Output

Output only one integer, the minimum total cost.

Sample Input

3 11 102 1010 32 3 1000

Sample Output

13

解析

这道题实际上是最小割问题。当问题要求将某些东西分为两堆,计算最小代价,就应该敏感地想到最小割模型。首先建图,如果把程序放在A,点归在左边(即在集合S中)。如果把程序放在B,点归在右边(即在集合T中)。然后最小割割开的部分就是代价。


根据最大流最小割定理,最大流=最小割。所以建好图后求最大流即可。

//dinic#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#include<queue>using namespace std;#define INF ~0u>>2struct EDGE{int from,to,residual;};vector<EDGE> Edge;vector<int> Chain[20010];int N,M,dis[20010],SuperS,SuperT;void insert(int s,int t,int f){Edge.push_back( (EDGE) {s,t,f} );Edge.push_back( (EDGE) {t,s,0} );Chain[s].push_back(Edge.size()-2);Chain[t].push_back(Edge.size()-1);}void readdata(){SuperS=0; SuperT=N+1;for(int i=1;i<=N;i++){int a,b;scanf("%d%d",&a,&b);insert(SuperS,i,a);insert(i,SuperT,b);}for(int i=1;i<=M;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);insert(a,b,c); insert(b,a,c);}}bool bfs(){memset(dis,0,sizeof(dis));queue<int> q; q.push(SuperS); dis[SuperS]=1;while(!q.empty()){int v=q.front(); q.pop();for(vector<int>::iterator u=Chain[v].begin();u!=Chain[v].end();u++)//u是边的编号if(!dis[Edge[*u].to] && Edge[*u].residual>0){dis[Edge[*u].to]=dis[Edge[*u].from]+1;q.push(Edge[*u].to);if(Edge[*u].to == SuperT) return 1;}}return 0;}int dfs(int v,int flow){if(v==SuperT || flow==0) return flow;int ans=0;for(vector<int>::iterator u=Chain[v].begin();u!=Chain[v].end();u++)if(dis[Edge[*u].to]==dis[Edge[*u].from]+1 && Edge[*u].residual>0){int tmp=dfs(Edge[*u].to,min(Edge[*u].residual,flow-ans));ans+=tmp;Edge[*u].residual-=tmp; Edge[(*u)^1].residual+=tmp;if(ans==flow) return ans;}return ans;}void dinic(){int ans=0;while(bfs()) ans+=dfs(SuperS,INF);printf("%d",ans);}int main(){freopen("poj3469.in","r",stdin);while(scanf("%d%d",&N,&M)==2){readdata();dinic();printf("\n");}while(1);return 0;}



0 0
原创粉丝点击