链接:http://poj.org/problem?id=3469
题意:有一个双核CPU,有n个模块需要在cpu上处理,在两个核上运行的耗费分别是Ai和Bi,m对模块需要共享数据,如果它们运行在同一个cpu中,共享数据的耗费可以忽略不计,否则需要额外的费用。求最小总耗费值。
思路:将两个cpu视为源点、汇点,模块视为图中顶点,对于每个Ai和Bi,可以从源点连一条容量为Ai的弧到i,从i连一条容量为Bi的弧到汇点,对于两个模块之间需要共享数据的情况,在它们之间连两条弧,正向和反向,容量为额外耗费,此时每个顶点都和源点、汇点相连,即每个顶点都可以在任意一个cpu中运行。
这样构图,对于图中任意一个割,源点、汇点都不是连通的,因此每个顶点都不可能同时和源点及汇点相连,也即每个顶点只能在一个cpu中运行。此时耗费即为割的容量,要让割的容量最小,根据最大流最小割定理,只需求原图的最大流即可。
这回我顺手写了昨天的优化,T了。。。用原来的代码,反而AC了,虽然也比较慢将近10s,我决定以后对边比较多的图还是用原来的写法,对边少的用类似多路增广优化的写法。
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 500100 #define eps 1e-7 #define INF 0x7FFFFFFF #define LLINF 0x7FFFFFFFFFFFFFFF #define seed 131 #define mod 1000000007 #define ll long long #define ull unsigned ll #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct node{ int u,w,next; }edge[MAXN]; int head[20100],dist[20100]; int cnt,n,m,src,sink; void add_edge(int a,int b,int c){ edge[cnt].u = b; edge[cnt].w = c; edge[cnt].next = head[a]; head[a] = cnt++; } bool bfs(){ int i,j; memset(dist,-1,sizeof(dist)); dist[src] = 1; queue<int>q; q.push(src); while(!q.empty()){ int u = q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].next){ int v = edge[i].u; if(dist[v]==-1&&edge[i].w){ dist[v] = dist[u] + 1; q.push(v); } } } if(dist[sink]==-1) return false; else return true; } int dfs(int u,int delta){ int i,j,dd; if(u==sink) return delta; int ret = 0; for(i=head[u];i!=-1;i=edge[i].next){ int v = edge[i].u; if(dist[v]==dist[u]+1&&edge[i].w){ dd = dfs(v,min(edge[i].w,delta)); edge[i].w -= dd; edge[i^1].w += dd; ret += dd; delta -= dd; } } return ret; } int main(){ int i,j; int a,b,c; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); cnt = 0; src = 0; sink = n + 1; for(i=1;i<=n;i++){ scanf("%d%d",&a,&b); add_edge(src,i,a); add_edge(i,src,0); add_edge(i,sink,b); add_edge(sink,i,0); } for(i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } int ans = 0; while(bfs()){ ans += dfs(src,INF); } printf("%d\n",ans); return 0; }
POJ--3469--Dual Core CPU【Dinic】最小割
时间: 2024-10-05 23:55:03