HDu Battle

  1 #include <iostream>//最大权闭合子图模板题
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 #define min(a,b) ((a)<(b))?(a):(b)
  9 #define max(a,b) ((a)>(b))?(a):(b)
 10 #define MAXN 1111+10
 11 #define MAXM 505000+10//M取N的平方倍
 12 #define INF 0x3f3f3f3f
 13 
 14 struct node
 15 {
 16     int n;//点编号
 17     int w;//点权
 18 }Node[MAXN];
 19 //链式前向星
 20 struct enode
 21 {
 22     int t;
 23     int w;                //权值
 24     int c;                //流量
 25 //  int cost;
 26 //    int pre;            //前向指针
 27     int next;
 28 };
 29 
 30 
 31     struct enode e[MAXM];
 32     int box[MAXN],ecnt;
 33     //int etail[MAXN];        //尾部
 34     void init()
 35     {
 36         ecnt=0;
 37         memset(box,-1,sizeof(box));
 38     //    memset(etail,-1,sizeof(etail));        //初始化尾部
 39     }
 40     void addedge(int f,int t,int c)            //流量重载
 41     {
 42         e[ecnt].next=box[f];
 43         e[ecnt].t=t;
 44         e[ecnt].c=c;
 45         box[f]=ecnt++;
 46         e[ecnt].next=box[t];
 47         e[ecnt].t=f;
 48         e[ecnt].c=0;
 49         box[t]=ecnt++;
 50     }
 51 int sap(int s,int t,int N)//最大流问题
 52 {
 53     int gap[MAXN],lvl[MAXN],cur[MAXN],pre[MAXN];
 54     int curflow,ans=0,u,tmp,neck,i;
 55     memset(lvl,0,sizeof(lvl));
 56     memset(gap,0,sizeof(gap));
 57     memset(pre,-1,sizeof(pre));
 58     for(i=0;i<N;i++)
 59         cur[i]=box[i];
 60     gap[0]=N;
 61     u=s;
 62     while(lvl[s]<N)
 63     {
 64         if(u==t)
 65         {
 66             curflow=INF;
 67             for(i=s;i!=t;i=e[cur[i]].t)
 68             {
 69                 if(curflow>e[cur[i]].c)
 70                 {
 71                     neck=i;
 72                     curflow=e[cur[i]].c;
 73                 }
 74             }
 75             for(i=s;i!=t;i=e[cur[i]].t)
 76             {
 77                 tmp=cur[i];
 78                 e[tmp].c-=curflow;
 79                 e[tmp^1].c+=curflow;
 80             }
 81             ans+=curflow;
 82             u=neck;
 83         }
 84         for(i=cur[u];i!=-1;i=e[i].next)
 85             if(e[i].c && lvl[u]==lvl[e[i].t]+1)
 86                 break;
 87         if(i!=-1)
 88         {
 89             cur[u]=i;
 90             pre[e[i].t]=u;
 91             u=e[i].t;
 92         }
 93         else
 94         {
 95             if(--gap[lvl[u]]==0)
 96                 break;
 97              cur[u]=box[u];
 98             for(tmp=N,i=box[u];i!=-1;i=e[i].next)
 99                 if(e[i].c)
100                     tmp=min(tmp,lvl[e[i].t]);
101             lvl[u]=tmp+1;
102             gap[lvl[u]]++;
103             if(u!=s)
104                 u=pre[u];
105         }
106     }
107     return ans;
108 }
109 int main()
110 {
111      int m,n,a,b,t;
112      int i,j,k;
113      int start,end,ans;
114    while(scanf("%d%d",&n,&m)!=EOF)  //;
115    {
116          start=ans=0;
117          end=1+n;//终点编号
118          init();
119          for(i=1;i<=n;i++)
120          {
121              scanf("%d",&Node[i].w);
122              if(Node[i].w>0)
123              {
124                  ans+=Node[i].w;
125                  addedge(start,i,Node[i].w);//起点建边
126              }
127              else if(Node[i].w<0)
128              {
129                  addedge(i,end,0-Node[i].w);//负点权点和终点相连
130              }
131              Node[i].n=i;
132          }
133          for(i=1;i<=m;i++)
134          {
135              scanf("%d%d",&a,&b);
136              addedge(a,b,INF);
137          }
138          t=sap( start,end,end+1);
139          printf("%d\n",ans-t);
140    }
141     return 0;
142 }
143 /*
144 Sample Input
145 
146 5 5
147 8
148 -8
149 -10
150 12
151 -10
152 
153 1 2
154 2 5
155 1 4
156 3 4
157 4 5
158 
159 Sample Output
160 
161 2
162 */

 

posted on 2013-04-24 22:53  ACM_Someone like you  阅读(216)  评论(0编辑  收藏  举报

导航