zoukankan      html  css  js  c++  java
  • poj 3469 Dual Core CPU

    题目描述:
    由于越来越多的计算机配置了双核CPU,TinySoft公司的首席技术官员,SetagLilb,决定升
    级他们的产品-SWODNIW。
    SWODNIW包含了N个模块,每个模块必须运行在某个CPU中。每个模块在每个CPU中
    运行的耗费已经被估算出来了,设为Ai和Bi。同时,M对模块之间需要共享数据,如果他们运行
    在同一个CPU中,共享数据的耗费可以忽略不计,否则,还需要额外的费用。你必须很好地安排
    这N个模块,使得总耗费最小。

    思路: 如果将两个CPU分别视为源点和汇点、模块视为顶点,则可以按照以下方式构图:对于第i
    个模块在每个CPU中的耗费Ai和Bi, 从源点向顶点i连接一条容量为Ai的弧、从顶点i向汇点
    连接一条容量为Bi的弧;对于a模块与b模块在不同CPU中运行造成的额外耗费w,顶点a
    与顶点b连接一条容量为w的弧。此时每个顶点(模块)都和源点及汇点(两个CPU)相连,即
    每个模块都可以在任意一个CPU中运行
    不难了解到,对于图中的任意一个割,源点与汇点必不连通。因此每个顶点(模块)都不可
    能同时和源点及汇点(两个CPU)相连,即每个模块只在同一个CPU中运行。此时耗费即为割
    容量。很显然,当割的容量取得最小值时,总耗费最小。故题目转化为求最小割的容量。


    #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <string.h> using namespace std; #define MOD 1000000007 #define maxn 20010 #define maxm 1000000 #define LL long long struct Eg{ int to; int next; int f; }E[maxm]; int V[maxn],num; int N,M; void add(int u,int v,int c){ E[num].to=v; E[num].f=c; E[num].next=V[u]; V[u]=num++; E[num].to=u; E[num].f=0; E[num].next=V[v]; V[v]=num++; } int level[maxn]; int qu[maxn]; bool BFS(int s,int t){ int i,iq=0; // memset(level,0,sizeof(level)); for(i=0;i<=t;i++) level[i]=0; //queue<int> Q; int u,v,e; qu[iq++]=s;// Q.push(s); level[s]=1; // while(!Q.empty()){ for(i=0;i<iq;i++){ u=qu[i];//Q.front(); //Q.pop(); if(u==t) return true; for(e=V[u];e!=-1;e=E[e].next){ v=E[e].to; if(!level[v]&&E[e].f>0) { level[v]=level[u]+1; qu[iq++]=v;// Q.push(v); } } } return false; } int cur[maxn]; int dfs(int u,int maxf,int t){ if(u==t||maxf==0) return maxf; int ret=0,f,e,v; for(e=cur[u];e!=-1;e=E[e].next){// 当前弧优化 v=E[e].to; if(E[e].f>0&&level[u]+1==level[v]){ f= dfs(v,min(maxf,E[e].f),t); E[e].f-=f; E[e^1].f+=f; maxf-=f; ret+=f; cur[u]=e; if(maxf==0) break; } } return ret; } int Dinic(int s,int t){ int flow=0; while(BFS(s,t)){ for(int i=0;i<=t;i++) cur[i]=V[i]; flow+=dfs(s,MOD,t); } return flow; } int main(){ int i; int a,b,w; while(scanf("%d %d",&N,&M)!=EOF){ for(i=0;i<=N+1;i++)V[i]=-1; num=0; for(i=1;i<=N;i++){ scanf("%d %d",&a,&b); add(0,i,a); add(i,N+1,b); } while(M--){ scanf("%d %d %d",&a,&b,&w); add(a,b,w); add(b,a,w); } printf("%d ",Dinic(0,N+1)); } return 0; }
  • 相关阅读:
    DateUtil(比较两个日期是否是同一天)
    用过的读写
    小笔记
    日志解析LogParse启动参数配置
    wow经典台词
    Quartz资源收藏
    Quartz Job基本示例
    已知两点坐标,及在从其中一点开始移动的距离,求移动到的坐标
    如何为SUSE配置IP地址,网关和DNS
    详解Linux Initrd
  • 原文地址:https://www.cnblogs.com/372465774y/p/3230421.html
Copyright © 2011-2022 走看看