POJ 1637 Dual Core CPU 求最小割

据说这道题目是个很经典的题,好多人测最大流算法效率都是用的这题,只会dinic的弱菜第一法果断tle了,把vector改成数组了时候5s过。

下次什么时候学了isap在写一遍把

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 20000 + 5;
const int maxm = 200000 * 30;
const LL INF = INT_MAX - 2;
int first[maxn],nxt[maxm],v[maxm],cap[maxm];
int n,m,s,t,ans,ecnt;

inline void adde(int uu,int vv,int ww) {
    v[ecnt] = vv; cap[ecnt] = ww;
    nxt[ecnt] = first[uu];
    first[uu] = ecnt++;
    v[ecnt] = uu; cap[ecnt] = 0;
    nxt[ecnt] = first[vv];
    first[vv] = ecnt++;
}

inline void input() {
    int a,b,c;
    for(int i = 1;i <= n;i++) {
        scanf("%d%d",&a,&b);
        adde(s,i,a); adde(i,t,b);
    }
    for(int i = 1;i <= m;i++) {
        scanf("%d%d%d",&a,&b,&c);
        adde(a,b,c);
        adde(b,a,c);
    }
}

int q[maxn * 2],qs,qe,level[maxn];
inline bool bfs() {
    qs = qe = 0;
    memset(level,0,sizeof level);
    q[qe++] = s;
    level[s] = 1;
    while(qs < qe) {
        int now = q[qs++];
        if(now == t) break;
        for(int i = first[now];~i;i = nxt[i]) {
            if(!level[v[i]] && cap[i]) {
                level[v[i]] = level[now] + 1;
                q[qe++] = v[i];
            }
        }
    }
    return level[t];
}

int dfs(int now,int alpha) {
    if(now == t) return alpha;
    int sum = 0;
    for(int i = first[now];~i && alpha;i = nxt[i]) {
        if(level[v[i]] == level[now] + 1 && cap[i]) {
            int ret = dfs(v[i],min(alpha,cap[i]));
            cap[i] -= ret; cap[i ^ 1] += ret;
            sum += ret; alpha -= ret;
        }
    }
    if(sum == 0) level[now] = -1;
    return sum;
}

inline int dinic() {
    int ans = 0;
    while(bfs()) ans += dfs(s,INF);
    return ans;
}

inline void solve() {
    int ret = dinic();
    printf("%d\n",ret);
}

int main() {
    while(scanf("%d%d",&n,&m) != EOF) {
        ecnt = 0;
        s = 0; t = n + 1;
        memset(first,-1,sizeof(first));
        input();
        solve();
    }
    return 0;
}

  

POJ 1637 Dual Core CPU 求最小割

时间: 2024-10-23 23:12:36

POJ 1637 Dual Core CPU 求最小割的相关文章

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【最小割】

Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 20852   Accepted: 9010 Case Time Limit: 5000MS Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Officer of TinySoft Co

POJ - 3469 Dual Core CPU (最小割)

(点击此处查看原题) 题意介绍 在一个由核A和核B组成的双核CPU上执行N个任务,任务i在核A上执行,花费Ai,在核B上执行,花费为Bi,而某两个任务之间可能需要进数据交互,如果两个任务在同一个核上执行,那么数据交互将没有花费,如果在不同核上执行,将产生wi的花费,问将n个任务全部执行产生的最小花费 . 解题思路 题目要求将n个任务分配为两个不同的集合,使得执行n个任务总花费最少,这类的题目我们一般将其转化为最小割问题,即花费最小的代价将n个点分为两部分.建图如下: 1)由源点向每个任务建一条容

POJ3469 Dual Core CPU(最小割)

形象生动的最小割.. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 2222 8 #define MAXM 888888 9 10 struct Edge{ 11 int v,cap,flow,next; 12 }ed

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

POJ3469_Dual Core CPU(网络流/最小割=最大流/模版)----Dinic模版2.0

解题报告 题目传送门 题意: 双核CPU,n个模块,每个模块必须运行在某个CPU核心上,每个模块在cpu单核的消耗A和B,M对模块要共享数据,如果在同一个核心上不用消耗,否则需要耗费.安排N个模块,使得总耗费最小 思路: 将两个cpu核心看成源点和汇点,其他模块分别与源点汇点连线(表示每个模块可以在任意cpu上运行),m对模块分别连双向边,要使得模块只能在一个cpu上运行,就是找到一个割,源点和汇点必不联通,耗费最少就是最小割,最小割最大流原理转换成求最大流. 这题数据大,没优化TLE了,加了两

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

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