BZOJ 1497 最大权闭合图

题解:

边由被限制节点指向限制节点

 

View Code
 1 #include <iostream>

 2 #include <algorithm>

 3 #include <cstring>

 4 #include <cstdlib>

 5 #include <cstdio>

 6 

 7 #define N 120000

 8 #define M 2000100

 9 #define INF 1e9

10 

11 using namespace std;

12 

13 int head[N],next[M],to[M],len[M];

14 int layer[N],q[M];

15 int n,m,cnt,S,T,sum;

16 

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

18 {

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

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

21 }

22 

23 inline void read()

24 {

25     memset(head,-1,sizeof head); cnt=0;

26     S=0; T=n+m+1; sum=0;

27     for(int i=1,a;i<=n;i++)

28     {

29         scanf("%d",&a);

30         add(i+m,T,a);

31     }

32     for(int i=1,a,b,c;i<=m;i++)

33     {

34         scanf("%d%d%d",&a,&b,&c);

35         add(S,i,c); add(i,a+m,INF); add(i,b+m,INF);

36         sum+=c;

37     }

38 }

39 

40 inline bool bfs()

41 {

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

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

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

45     while(h<t)

46     {

47         sta=q[h++];

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

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

50             {

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

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

53             }

54     }

55     return layer[T]!=-1;

56 }

57 

58 inline int find(int u,int cur_flow)

59 {

60     if(u==T) return cur_flow;

61     int res=0,tmp;

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

63         if(len[i]&&layer[to[i]]==layer[u]+1)

64         {

65             tmp=find(to[i],min(cur_flow-res,len[i]));

66             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;

67         }

68     if(!res) layer[u]=-1;

69     return res;

70 }

71 

72 inline void go()

73 {

74     int ans=0;

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

76     printf("%d\n",sum-ans);

77 }

78 

79 int main()

80 {

81     while(scanf("%d%d",&n,&m)!=EOF) read(),go();

82     return 0;

83 }

 

 

你可能感兴趣的:(ZOJ)