Dual Core CPU

这题建图方式:第一核做源点(S = 0),第二核做汇点(T = N +1),每个模块的双核花费<Ai, Bi>,加边<S, i, Ai>, <i, T, Bi>,如果不在同一核上操作,虚假额外花费,即加双向容量,加边<a, b, w>, <b, a, w>。剩下的就是实现方法了,我这里用dinic来实现的。

今天学习了下dinic,学的一头雾水,对着模板敲,终于过了,稍稍懂了点什么叫dinic,原来dinic是层次化思想,每次不是回到源点搜,而是回到找到最小增流的地方继续增广。2007年论文《浅谈基于分层思想的网络流算法》有讲解,具体步骤可以分成四点:

1、初始化流量,计算出剩余图

2、一次bfs对顶点标号,计算出层次图,如果汇点不在层次图内,那么算法结束

3、一次dfs过程找增广
4、转步骤 2
这里第三步我是用多次dfs找增广,貌似更快!
代码
#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define MM 480008
#define NN 20004
#define INF 0xfffffff
typedef
struct node{
int adjVer, wet, nxt;
}edgeNode;

edgeNode edg[MM];
int link[NN];
int h[NN];

int M, N, idx, S, T;
int Min(int a, int b){
return a < b ? a : b;
}
void add(int u, int v, int x, int y){
edg[idx].adjVer
= v;
edg[idx].wet
= x;
edg[idx].nxt
= link[u];
link[u]
= idx++;

edg[idx].adjVer
= u;
edg[idx].wet
= y;
edg[idx].nxt
= link[v];
link[v]
= idx++;
}
/*找到层次图*/
int bfs()
{
int i, head, tail, u, v, w, tmp;
int que[NN];
for (i = 0; i <= N + 1; i++) h[i] = -1;
que[
0] = S;
h[S]
= 0;
head
= tail = 0;
while (head <= tail){
u
= que[head++];
for (tmp = link[u]; tmp != -1; tmp = edg[tmp].nxt){
v
= edg[tmp].adjVer;
w
= edg[tmp].wet;
if (h[v] == -1 && w > 0){
h[v]
= h[u] + 1;
que[
++tail] = v;
}
}
}
return h[T] != -1;
}

int dfs(int u, int flow){
if (u == T) return flow;

int tmpf, minf, v, w, tmp;
tmpf
= 0;
for (tmp = link[u]; tmp != -1; tmp = edg[tmp].nxt){
v
= edg[tmp].adjVer;
w
= edg[tmp].wet;
if (h[v] == h[u] + 1 && w > 0 && tmpf < flow && (minf = dfs(v, Min(w, flow - tmpf)))){
edg[tmp].wet
-= minf;
edg[tmp
+ !(tmp % 2)].wet += minf; // 将反向边也更改一下,由于正反向边是相邻加入边的,所以可以这样来改
tmpf += minf;
}
}
if (tmpf == 0){
h[u]
= -1;
}
return tmpf;
}
void dinic()
{
int t, ans = 0;
while (bfs()){
while(t = dfs(S, INF))
ans
+= t;
}
printf(
"%d\n", ans);
}
int main()
{
int i, a, b, w, idx = 0;
scanf(
"%d%d", &N, &M);
S
= 0;
T
= N + 1;
memset(link,
-1, sizeof(link));
for (i = 1; i <= N; i++){
scanf(
"%d%d", &a, &b);
add(
0, i, a, 0);
add(i, N
+ 1, b, 0);
}
for (i = 1; i <= M; i++){
scanf(
"%d%d%d", &a, &b, &w);
add(a, b, w, w);
}
dinic();
//system("pause");
return 0;
}

 

posted on 2010-07-27 21:03  ylfdrib  阅读(588)  评论(0编辑  收藏  举报