您的位置:首页 > 其它

POJ 3469 Dual Core CPU <Dinic + 最小割 + 最大流>

2016-08-05 22:06 337 查看
传送门:http://poj.org/problem?id=3469

题意:要在由核A核B组成的双核CPU上运行N个模块。模块i在核A执行花费时间为Ai,在核B花费时间为Bi。有M个相互之间需要进行数据交换(ai,bi),如果这两个在同一个核,不计算,否则需花费wi。求所要花费最小多少?

分析:最小割转化为最大流

Dinic求最大流,VElogV,数据量大,其他方法容易TLE

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;

#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 200010
#define MOD 1000000007

struct Edge
{
int to, val, next;
} edge[2000000];
int n, m, tot;
int head[20100], level[20100], cur[20100];

void add_edge(int from, int to, int val)
{
edge[tot].to = to;
edge[tot].val = val;
edge[tot].next = head[from];
head[from] = tot++;
edge[tot].to = from;
edge[tot].val = 0;
edge[tot].next = head[to];
head[to] = tot++;
}
int bfs(int s,int t)
{
queue<int> que;
que.push(s);
memset(level,-1,sizeof(level));
level[s] = 0;
while(!que.empty())
{
int v = que.front();
que.pop();
int u = head[v];
for(; u != -1; u = edge[u].next)
if(edge[u].val > 0 && level[edge[u].to] == -1)
{
level[edge[u].to] = level[v] + 1;
que.push(edge[u].to);
if(edge[u].to == t)
return 1;
}
}
return 0;
}
int dfs(int u,int cnt)
{
if(u == n+1)
return cnt;
int result = 0,tmp = 0;
for(int i = head[u]; i != -1 && result < cnt; i = edge[i].next)
if(edge[i].val > 0 && level[edge[i].to] == level[u] + 1)
{
tmp = dfs(edge[i].to,min(edge[i].val,cnt - result));
edge[i].val -= tmp;
edge[i^1].val += tmp;
result += tmp;
}
if(!result)
level[u] = -1;
return result;
}
int dinic(int s,int t)
{
int ans = 0;
while(bfs(s,t))
ans += dfs(s,INF);
return ans;
}
void init()
{
memset(head, -1, sizeof(head));
tot = 0;
}
int main()
{
int s,t;
while(scanf("%d%d", &n, &m) != EOF)
{
int a, b, c;
s = 0,t=n+1;
init();
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &a, &b);
add_edge(s, i, a);
add_edge(i, t, b);
}
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &a, &b,&c);
add_edge(a, b, c);
add_edge(b, a, c);
}
printf("%d\n", dinic(s,t));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: