• POJ3469 Dual Core CPU


    嘟嘟嘟

    一道最小割典型题。

    对于一个模块x,我们把他拆成两个点x1, x2:从源点向x1连一条ai的边,割掉他代表x在A机器上的花费;同理x2向汇点连一条bi的边,割掉他代表在B机器上的花费。因为每一个模块必须完成,所以x1和x2连一条INF的边,割掉他的代价是无穷的。

    题中还说如果x和y不在同一机器完成的话,会付出额外的代价。所以我们把x1和y1,x2和y2连一条边权为这个代价的边。

    然后跑最大流求最小割即可。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 4e4 + 5;
     21 const int maxe = 1e7 + 5;
     22 inline ll read()
     23 {
     24   ll ans = 0;
     25   char ch = getchar(), last = ' ';
     26   while(!isdigit(ch)) {last = ch; ch = getchar();}
     27   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     28   if(last == '-') ans = -ans;
     29   return ans;
     30 }
     31 inline void write(ll x)
     32 {
     33   if(x < 0) x = -x, putchar('-');
     34   if(x >= 10) write(x / 10);
     35   putchar(x % 10 + '0');
     36 }
     37 
     38 int n, m, t;
     39 
     40 struct Edge
     41 {
     42   int nxt, from, to, cap, flow;
     43 }e[maxe];
     44 int head[maxn], ecnt = 1;
     45 void addEdge(int x, int y, int w)
     46 {
     47   e[++ecnt] = (Edge){head[x], x, y, w, 0};
     48   head[x] = ecnt;
     49   e[++ecnt] = (Edge){head[y], y, x, 0, 0};
     50   head[y] = ecnt;
     51 }
     52 
     53 int dis[maxn];
     54 bool bfs()
     55 {
     56   Mem(dis, 0); dis[0] = 1;
     57   queue<int> q; q.push(0);
     58   while(!q.empty())
     59     {
     60       int now = q.front(); q.pop();
     61       for(int i = head[now]; i; i = e[i].nxt)
     62     {
     63       if(!dis[e[i].to] && e[i].cap > e[i].flow)
     64         {
     65           dis[e[i].to] = dis[now] + 1;
     66           q.push(e[i].to);
     67         }
     68     }
     69     }
     70   return dis[t];
     71 }
     72 int cur[maxn];
     73 int dfs(int now, int res)
     74 {
     75   if(now == t || res == 0) return res;
     76   int flow = 0, f;
     77   if(!cur[now]) cur[now] = head[now];
     78   for(int &i = cur[now]; i; i = e[i].nxt)
     79     {
     80       if(dis[e[i].to] == dis[now] + 1 && (f = dfs(e[i].to, min(res, e[i].cap - e[i].flow))) > 0)
     81     {
     82       e[i].flow += f; e[i ^ 1].flow -= f;
     83       flow += f; res -= f;
     84       if(res == 0) break;
     85     }
     86     }
     87   return flow;
     88 }
     89 
     90 int minCut()
     91 {
     92   int flow = 0;
     93   while(bfs())
     94     {
     95       Mem(cur, 0);
     96       flow += dfs(0, INF);
     97     }
     98   return flow;
     99 }
    100 
    101 int main()
    102 {
    103   n = read(); m = read(); t = n + n + 1;
    104   for(int i = 1; i <= n; ++i)
    105     {
    106       int x = read(), y = read();
    107       addEdge(0, i, x); addEdge(i + n, t, y);
    108       addEdge(i, i + n, INF);
    109     }
    110   for(int i = 1; i <= m; ++i)
    111     {
    112       int x = read(), y = read(), w = read();
    113       addEdge(x, y, w); addEdge(y, x, w);
    114       addEdge(x + n, y + n, w); addEdge(y + n, x + n, w);
    115     }
    116   write(minCut()), enter;
    117   return 0;
    118 }
    View Code
  • 相关阅读:
    struts2文件上传报错
    简述算法和程序的区别并举例说明
    JAVA中TreeMap集合筛选字母及每一个字符出现的次数
    Myeclipse2014破解步骤
    修改ubuntu的终端提示符
    gcc 引用math.h头文件,编译出现undefined reference to `pow‘等错误时,需要加参数lm.
    几篇文章
    gdb调试gcc出现:Missing separate debuginfos, use: debuginfoinstall glibcx.i686
    【达内C++学习培训学习笔记系列】C语言之三循环语句和数组
    code::block之spell checker配置
  • 原文地址:https://www.cnblogs.com/mrclr/p/9814741.html
Copyright © 2020-2023  润新知