POJ 3469(Dual Core CPU-最小割)[Template:网络流dinic V2]


Language:
Default

Dual Core CPU

Time Limit: 15000MS   Memory Limit: 131072K
Total Submissions: 19321   Accepted: 8372
Case Time Limit: 5000MS

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
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: abw. 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
between them.

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

最小割的模板,其实就是最大流

注意:

Verson 2:

1.修复Bug,在本次模板中修改了q队列的长度,

题目,裸最小割,

设S为用模块A的集合,T为模块B

s->任务i  //模块B的cost

任务i->t  //模块A的cost

任务i->任务j //(i,j)不在一个集合的cost,注意最小割,要2个方向(最小割只保证s->t没路径,t->s的路径不用割)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXn (20000+10)
#define MAXm (200000+10)
#define MAXN (MAXn+2)
#define MAXM ((MAXn*2+MAXm*2)*2+100)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
class Max_flow  //dinic+当前弧优化
{
public:
    int n,s,t;
    int q[MAXN];
    int edge[MAXM],next[MAXM],pre[MAXN],weight[MAXM],size;
    void addedge(int u,int v,int w)
    {
        edge[++size]=v;
        weight[size]=w;
        next[size]=pre[u];
        pre[u]=size;
    }
    void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,0);}
    bool b[MAXN];
    int d[MAXN];
    bool SPFA(int s,int t)
    {
        For(i,n) d[i]=INF;
        MEM(b)
        d[q[1]=s]=0;b[s]=1;
        int head=1,tail=1;
        while (head<=tail)
        {
            int now=q[head++];
            Forp(now)
            {
                int &v=edge[p];
                if (weight[p]&&!b[v])
                {
                    d[v]=d[now]+1;
                    b[v]=1,q[++tail]=v;
                }
            }
        }
        return b[t];
    }
    int iter[MAXN];
    int dfs(int x,int f)
    {
        if (x==t) return f;
        Forpiter(x)
        {
            int v=edge[p];
            if (weight[p]&&d[x]<d[v])
            {
                  int nowflow=dfs(v,min(weight[p],f));
                  if (nowflow)
                  {
                    weight[p]-=nowflow;
                    weight[p^1]+=nowflow;
                    return nowflow;
                  }
            }
        }
        return 0;
    }
    int max_flow(int s,int t)
    {
        int flow=0;
        while(SPFA(s,t))
        {
            For(i,n) iter[i]=pre[i];
            int f;
            while (f=dfs(s,INF))
                flow+=f;
        }
        return flow;
    }
    void mem(int n,int s,int t)
    {
        (*this).n=n;
        (*this).t=t;
        (*this).s=s;    

        size=1;
        MEM(pre)
    }
}S;    

int n,m;

int main()
{
//	freopen("poj3469.in","r",stdin);
//	freopen(".out","w",stdout);

	scanf("%d%d",&n,&m);

	int s=1,t=n+2;
	S.mem(n+2,s,t);
	For(i,n)
	{
		int ai,bi;
		scanf("%d%d",&ai,&bi);
		S.addedge2(i+1,t,ai);
		S.addedge2(s,i+1,bi);
	}

	For(i,m)
	{
		int a,b,w;
		scanf("%d%d%d",&a,&b,&w);
		S.addedge(a+1,b+1,w);
		S.addedge(b+1,a+1,w);
	}

	cout<<S.max_flow(s,t)<<endl;

	return 0;
}
时间: 2024-10-21 13:15:37

POJ 3469(Dual Core CPU-最小割)[Template:网络流dinic V2]的相关文章

poj 3469 Dual Core CPU 最小割

题意: 有n个模块在A和B核组成的双核计算机上运行,各个模块在A,B核上的运行时间已知,另外有m个三元组(a,b,w),表示a模块和b模块如果不在一个核上运行要产生w的额外花销,求总的最小花销. 分析: 即把n个模块划分为两个集合,可用求最小割的方法解决. 代码: //poj 3469 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const i

poj 3469 Dual Core CPU——最小割

题目:http://poj.org/problem?id=3469 最小割裸题. 那个限制就是在 i.j 之间连双向边. 根据本题能引出网络流中二元关系的种种. 别忘了写 if ( x==n+1 ) return flow ; ! #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=2e4+5,M=2e5+

【网络流#8】POJ 3469 Dual Core CPU 最小割 - 《挑战程序设计竞赛》例题

[题意]有n个程序,分别在两个内核中运行,程序i在内核A上运行代价为ai,在内核B上运行的代价为bi,现在有程序间数据交换,如果两个程序在同一核上运行,则不产生额外代价,在不同核上运行则产生Cij的额外代价,问如何划分使得代价最小. 用最小的费用将对象划分为两个集合的问题,常常可以转换为最小割后顺利解决 建立源点与汇点,每个程序视为一个点,源点与在各个程序连一条边,最大流量为bi,汇点与各个程序连一条边,最大流量ai,对于有额外代价的程序,连一条双向边,流量为cij. 一开始用Dinic算法做,

poj 3469 Dual Core CPU 最大流最小割定理

#include<stdio.h> #include<string.h> #include<queue> #include<vector> using namespace std; const int N=200000+5; const int inf=1<<24; struct Edge { int from,to,cap,flow; }; vector<Edge>edges; vector<int>G[N]; int

POJ 3469 Dual Core CPU(最小割)

POJ 3469 Dual Core CPU 题目链接 题意:有a,b两台机器,有n个任务,在a机器和b机器需要不同时间,给定m个限制,如果u, v在不同机器需要额外开销,问最小开销 思路:最小割,源点为a机器,汇点为b机器,这样的话求出最小割,就是把点分成两个集合的最小代价,然后如果u, v在不同机器需要开销,则连u,v v,u两条边,容量为额外开销,这样如果这条边是割边,则a,b会在不同集合,并且代价就会被加上去 代码: #include <cstdio> #include <cst

POJ 3469 Dual Core CPU (求最小割)

POJ 3469 Dual Core CPU 链接:http://poj.org/problem?id=3469 题意:有两个cpu,n个模块.每个模块运行在连个cpu上运行时间不同.有m对模块之间要进行信息交互,如果模块在同一个cpu,那么进行信息交互时不需要额外时间,否则要花额外的时间.问怎么样分配模块,能够使得花费的时间最少. 思路:要将模块分给两个cpu,同时要使得时间最少,其实就是求最小割.那么题目可以转化为求最大流. 代码: /* ID: [email protected] PROG

POJ 3469 Dual Core CPU(网络流之最小割)

题目地址:POJ 3469 建图思路:建源点与汇点,源点与CPU1相连,汇点与CPU2相连,对共享数据的之间连无向边. 我的ISAP过这题还是毫无时间压力的嘛... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctyp

POJ 3469 Dual Core CPU 最大流

划分成两个集合使费用最小,可以转成最小割,既最大流. //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cm

poj3469 Dual Core CPU --- 最小割

一个CPU有两个核,要把n个模块放在其中一个核上,给出放在不同核上的花费. 另给出m对模块,若不放在同一模块则会产生额外花费.求最小花费. 对于每一个模块可以选择核1,核2,和相连的模块. 据此建边,核1为源点,核2为汇点,相连的模块之间建双向边,边权均为花费.求最小割即可. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmat