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

猜你喜欢

转载自www.cnblogs.com/mrclr/p/9814741.html
今日推荐