hdu 4280 最大流 sap模板

给你岛的坐标求最西边到最东边的最大流

  1 /*
  2 最大流模板
  3 sap
  4 */
  5 #include<stdio.h>
  6 #include<string.h>
  7 #include<algorithm>
  8 #include<iostream>
  9 using namespace std;
 10 
 11 const int MAXN=100010;//点数的最大值
 12 const int MAXM=400010;//边数的最大值
 13 const int INF=0x3f3f3f3f;
 14 
 15 struct Node
 16 {
 17     int from,to,next;
 18     int cap;
 19 }G[MAXM];
 20 int tol;
 21 int head[MAXN];
 22 int dep[MAXN];
 23 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
 24 
 25 int n;//n是总的点的个数,包括源点和汇点
 26 
 27 void init()
 28 {
 29     tol=0;
 30     memset(head,-1,sizeof(head));
 31 }
 32 
 33 void build(int u,int v,int w)
 34 {
 35     G[tol].from=u;
 36     G[tol].to=v;
 37     G[tol].cap=w;
 38     G[tol].next=head[u];
 39     head[u]=tol++;
 40     G[tol].from=v;
 41     G[tol].to=u;
 42     G[tol].cap=0;
 43     G[tol].next=head[v];
 44     head[v]=tol++;
 45 }
 46 void BFS(int st,int ed)
 47 {
 48     memset(dep,-1,sizeof(dep));
 49     memset(gap,0,sizeof(gap));
 50     gap[0]=1;
 51     int que[MAXN];
 52     int left,right;
 53     left=right=0;
 54     dep[ed]=0;
 55     que[right++]=ed;
 56     while(left!=right)
 57     {
 58         int u=que[left++];
 59         if(left==MAXN)left=0;
 60         for(int i=head[u];i!=-1;i=G[i].next)
 61         {
 62             int v=G[i].to;
 63             if(dep[v]!=-1)continue;
 64             que[right++]=v;
 65             if(right==MAXN)right=0;
 66             dep[v]=dep[u]+1;
 67             ++gap[dep[v]];
 68         }
 69     }
 70 }
 71 int SAP(int st,int ed)
 72 {
 73     int res=0;
 74     BFS(st,ed);
 75     int cur[MAXN];
 76     int S[MAXN];
 77     int top=0;
 78     memcpy(cur,head,sizeof(head));
 79     int u=st;
 80     int i;
 81     while(dep[st]<n){
 82         if(u==ed){
 83             int temp=INF;
 84             int inser;
 85             for(i=0;i<top;i++)
 86                if(temp>G[S[i]].cap){
 87                    temp=G[S[i]].cap;
 88                    inser=i;
 89                }
 90             for(i=0;i<top;i++){
 91                 G[S[i]].cap-=temp;
 92                 G[S[i]^1].cap+=temp;
 93             }
 94             res+=temp;
 95             top=inser;
 96             u=G[S[top]].from;
 97         }
 98         if(u!=ed&&gap[dep[u]-1]==0)//出现断层,无增广路
 99           break;
100         for(i=cur[u];i!=-1;i=G[i].next)
101             if(G[i].cap!=0&&dep[u]==dep[G[i].to]+1)
102              break;
103         if(i!=-1){
104             cur[u]=i;
105             S[top++]=i;
106             u=G[i].to;
107         }
108         else{
109             int min=n;
110             for(i=head[u];i!=-1;i=G[i].next){
111                 if(G[i].cap==0)continue;
112                 if(min>dep[G[i].to]){
113                     min=dep[G[i].to];
114                     cur[u]=i;
115                 }
116             }
117             --gap[dep[u]];
118             dep[u]=min+1;
119             ++gap[dep[u]];
120             if(u!=st)u=G[S[--top]].from;
121         }
122     }
123     return res;
124 }
125 
126 int main()
127 {
128     int st,ed;
129     int m;
130     int u,v,z;
131     int T;
132     scanf("%d",&T);
133 
134     while(T--){
135         init();
136         scanf("%d%d",&n,&m);
137         int minx=10000000;
138         int maxx=-10000000;
139         int x,y;
140         for(int i=1;i<=n;i++){
141             scanf("%d%d",&x,&y);
142             if(minx>x){
143                 minx=x;
144                 st=i;
145             }
146             if(maxx<x){
147                 maxx=x;
148                 ed=i;
149             }
150         }
151         while(m--){
152             scanf("%d%d%d",&u,&v,&z);
153             build(u,v,z);
154             build(v,u,z);
155         }
156         //n一定是点的总数,这是使用SAP模板需要注意的
157         int ans=SAP(st,ed);
158         printf("%d\n",ans);
159     }
160     return 0;
161 }

 

posted @ 2019-09-24 19:04  古比  阅读(203)  评论(0编辑  收藏  举报