题目链接:http://poj.org/problem?id=3469
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 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 extra w dollars for the data-exchange 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 |
[Submit] [Go Back] [Status]
[Discuss]
一道典型的最小割问题。
我们先假定两个额外的点,源点s,和汇点t。 我们记图中 s-t 割所对应的包含s的顶点集合为S,包含t集合为T。
对于顶点属于S时所产生的费用,只要从每个模块向t连一条容量为A[i]的边就可以对应起来,对于属于T的,只要从s向每个模块连一条容量为B[i]的边即可,接下对那些a[i]属于S,b[i]属于T时所产生的费用,只要从模块a[i]向模块b[i]连一条容量为w[i]的边就可以对应,对剩余情况同理可得。
code:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int MAX=200010; const int INF=1<<30; struct edge{int to,cap,rev;}; vector<edge> G[MAX]; int level[MAX]; int iter[MAX]; void add(int from,int to,int cap) { G[from].push_back((edge){to,cap,G[to].size()}); G[to].push_back((edge){from,0,G[from].size()-1}); } void bfs(int s) { memset(level,-1,sizeof(level)); queue<int> que; level[s]=0; que.push(s); while(!que.empty()) { int v=que.front(); que.pop(); for(int i=0;i<G[v].size();i++) { edge &e=G[v][i]; if(e.cap>0&& level[e.to]<0) { level[e.to]=level[v]+1; que.push(e.to); } } } } int dfs(int v,int t,int f) { if(v==t) return f; for(int &i=iter[v];i<G[v].size();i++) { edge &e=G[v][i]; if(e.cap>0&&level[v]<level[e.to]) { int d=dfs(e.to,t,min(f,e.cap)); if(d>0) { e.cap-=d; G[e.to][e.rev].cap+=d; return d; } } } return 0; } int max_flow(int s,int t) { int flow=0; for(;;) { bfs(s); if(level[t]<0) return flow; memset(iter,0,sizeof(iter)); int f; while((f=dfs(s,t,INF))>0) flow+=f; } } const int MAXV=20010; int N,M; int A[MAXV],B[MAXV]; int a[MAX],b[MAX],w[MAX]; void solve() { int s=N,t=s+1; for(int i=0;i<N;i++) { add(i,t,A[i]); add(s,i,B[i]); } for(int i=0;i<M;i++) { add(a[i]-1,b[i]-1,w[i]); add(b[i]-1,a[i]-1,w[i]); } cout<<max_flow(s,t)<<endl; } int main() { cin>>N>>M; for(int i=0;i<N;i++) { scanf("%d%d",&A[i],&B[i]); } for(int i=0;i<M;i++) { scanf("%d%d%d",&a[i],&b[i],&w[i]); } solve(); return 0; }
poj3469(最大流最小割问题)