双核 CPU
时间限制: 1 Sec 内存限制: 128 MB题目描述
由于越来越多的计算机配置了双核 CPU,TinySoft 公司的首席技术官员,SetagLilb,决定升级他们的产品-SWODNIW。
SWODNIW 包含了 N 个模块,每个模块必须运行在某个 CPU 中。每个模块在每个 CPU 中运行的耗费已经被估算出来了,设为 Ai 和 Bi。同时,M 对模块之间需要共享数据,如果他们运行在同一个 CPU 中,共享数据的耗费可以忽略不计,否则,还需要额外的费用。你必须很好地安排这 N 个模块,使得总耗费最小。
输入
测试数据的第 1 行为两个整数N 和 M,1≤N≤20000,1≤M≤200000。接下来有 N 行,每行为两个整数 Ai 和 Bi。接下来有 M 行,每行为 3 个整数 a, b, w,表示 a 模块和 b 模块如果不是在同一个 CPU 中运行,则需要花费额外的 w 耗费来共享数据。
输出
输出一个整数,为最小耗费。
样例输入
3 1
1 10
2 10
10 3
2 3 1000
样例输出
13
题解:
没什么好写的。
1.虚拟源点和汇点。
2.将点与源点和汇点分别连边,权值为CPU1和CPU2的消耗。
3.对于额外费用,直接将两点连边(双向边),权值为额外费用。
4.网络流跑起来!!!
代码如下:
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> #include<stack> #include<ctime> #include<vector> using namespace std; int n,m; int src,des; struct node { int next,to,cap; }edge[900005]; int head[20005],size=1; void putin(int from,int to,int cap) { size++; edge[size].to=to; edge[size].next=head[from]; edge[size].cap=cap; head[from]=size; } void in(int from,int to,int cap) { putin(from,to,cap); putin(to,from,0); } int dist[20005],numbs[20005]; void bfs(int src,int des) { int i,j; queue<int>mem; mem.push(des); dist[des]=0;numbs[0]++; while(!mem.empty()) { int x=mem.front();mem.pop(); for(i=head[x];i!=-1;i=edge[i].next) { int y=edge[i].to; if(edge[i].cap==0&&dist[y]==0&&y!=des) { dist[y]=dist[x]+1; numbs[dist[y]]++; mem.push(y); } } } return; } int dfs(int s,int flow,int des) { if(s==des)return flow; int i,mindist=n+2,low=0; for(i=head[s];i!=-1;i=edge[i].next) { int y=edge[i].to; if(edge[i].cap) { if(dist[y]==dist[s]-1) { int t=dfs(edge[i].to,min(flow-low,edge[i].cap),des); edge[i].cap-=t; edge[i^1].cap+=t; low+=t; if(dist[src]>=n+2)return low; if(low==flow)break; } mindist=min(mindist,dist[y]+1); } } if(!low) { if(!(--numbs[dist[s]]))dist[src]=n+2; ++numbs[dist[s]=mindist]; } return low; } int ISAP(int src,int des) { int ans=0; bfs(src,des); while(dist[src]<n+2) ans+=dfs(src,2e8,des); return ans; } int main() { int i,j; scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); src=0;des=n+1; for(i=1;i<=n;i++) { int a,b; scanf("%d%d",&a,&b); in(src,i,a); in(i,des,b); } for(i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); in(a,b,c); in(b,a,c); } int maxflow=ISAP(src,des); cout<<maxflow<<endl; return 0; }