POJ 3469 最小割

题意:

有一些模块(modules)和一个双核处理器,一个模块可以在任意一个核上处理,每个核对应每个模块有个开销。现在有一些模块间需要数据交换,如果需要数据交换的模块在一个核上处理,则不需要额外开销,否则需要加上一个开销。现在需要完成所有模块,问最小需要多少开销。

如果没有这个额外的开销,那么每个模块只要选择开销小的那个核就行了。额外的开销给选择加上了限制。

题解:

最小割模型。

S和T分别表示两个核,每个模块和S,T连边求最小割就是了~

 

View Code
 1 #include <cstdio>

 2 #include <cstdlib>

 3 #include <cstring>

 4 #include <iostream>

 5 

 6 #define N 201000

 7 #define M  2001000

 8 #define INF 100000000

 9 

10 using namespace std;

11 

12 int head[N],next[M],to[M],len[M],cnt,S,T,a[N],b[N],aa[M],bb[M],n,m,w[N],layer[N],q[M<<4]; 

13 

14 inline void add(int u,int v,int w)

15 {

16     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;

17     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;

18 }

19 

20 void read()

21 {

22     memset(head,-1,sizeof head);

23     for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);

24     for(int i=1;i<=m;i++)

25     {

26         scanf("%d%d%d",&aa[i],&bb[i],&w[i]);

27         add(aa[i],bb[i],w[i]); add(bb[i],aa[i],w[i]);

28     }

29     S=0; T=n+1;

30     for(int i=1;i<=n;i++) add(S,i,a[i]),add(i,T,b[i]);

31 }

32 

33 bool bfs()

34 {

35     memset(layer,-1,sizeof layer);

36     int h=1,t=2,sta;

37     q[1]=S; layer[S]=0;

38     while(h<t)

39     {

40         sta=q[h++];

41         for(int i=head[sta];~i;i=next[i])

42             if(len[i]>0&&layer[to[i]]<0)

43             {

44                 layer[to[i]]=layer[sta]+1;

45                 q[t++]=to[i];

46             }

47     }

48     return layer[T]!=-1;

49 }

50 

51 int find(int u,int cur_flow)

52 {

53     if(u==T) return cur_flow;

54     int result=0,tmp=0;

55     for(int i=head[u];~i&&result<cur_flow;i=next[i])

56         if(len[i]>0&&layer[to[i]]==layer[u]+1)

57         {

58             tmp=find(to[i],min(len[i],cur_flow-result));

59             len[i]-=tmp; len[i^1]+=tmp; result+=tmp;

60         }

61     if(!result) layer[u]=-1;

62     return result; 

63 }

64 

65 int dinic()

66 {

67     int ans=0;

68     while(bfs()) ans+=find(S,INF);

69     return ans;

70 }

71 

72 int main()

73 {

74     while(scanf("%d%d",&n,&m)!=EOF)

75     {

76         read();

77         printf("%d",dinic());

78     }

79     return 0;

80 }

 

 

你可能感兴趣的:(poj)