【模板】网络流isap

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e5+8;
  4 int cnt=1;
  5 struct edge{
  6     int to,nex,w;
  7 }e[2*N];
  8 int s,t,n,m;
  9 int h[N],cur[N],gap[N],dep[N],pre[N];
 10 void add(int a,int b,int w){
 11     e[++cnt]=(edge){b,h[a],w};
 12     h[a]=cnt;
 13 }
 14 void bfs(){
 15     memset(gap,0,(n+1)*sizeof(int));
 16     memset(dep,-1,(n+1)*sizeof(int));
 17     dep[t]=0;
 18     gap[0]=1;
 19     queue<int> q;
 20     q.push(t);
 21     while(!q.empty()){
 22         int u=q.front();
 23         q.pop();
 24         for(int i=cur[u]=h[u];i;i=e[i].nex){
 25             int v=e[i].to;
 26             if(dep[v]!=-1) continue;
 27             q.push(v);
 28             dep[v]=dep[u]+1;
 29             ++gap[dep[v]];
 30         }
 31     }
 32 }
 33 int cal(){
 34     int flow=0x3f3f3f3f;
 35     for(int i=s;i!=t;i=e[cur[i]].to) 
 36         flow=min(flow,e[cur[i]].w);
 37     for(int i=s;i!=t;i=e[cur[i]].to){
 38         e[cur[i]].w-=flow;
 39         e[cur[i]^1].w+=flow;
 40     }
 41     return flow;
 42 }
 43 int isap(){
 44     int ans=0;
 45     bfs();
 46     int u=s,v;
 47     while(dep[s]<n){
 48         if(u==t){
 49             ans+=cal();
 50             u=s;
 51         }
 52         bool fg=0;
 53         for(int i=cur[u];i;i=e[i].nex){
 54             if(e[i].w&&dep[u]>dep[v=e[i].to]){
 55                 pre[v]=u;
 56                 cur[u]=i;
 57                 u=v;
 58                 fg=1;
 59                 break;
 60             }
 61         }
 62         if(fg) continue;
 63         if(!--gap[dep[u]]) break;
 64         int maxdis=n;//n 是点数
 65         for(int i=h[u];i;i=e[i].nex){
 66             if(e[i].w && maxdis>dep[v=e[i].to]){
 67                 maxdis=dep[v];
 68                 cur[u]=i;
 69             }
 70         }
 71         gap[dep[u]=maxdis+1]++;
 72         if(u!=s) u=pre[u];
 73     }
 74     return ans;
 75 }
 76 int main(){
 77     int T;
 78     scanf("%d",&T);
 79     while(T--)
 80     {
 81         scanf("%d%d",&n,&m);
 82         int Max=0,Min=0x3f3f3f3f;
 83         cnt=1;
 84         memset(h,0,(n+1)*sizeof(int));
 85         for(int i=0; i<n; i++)
 86         {
 87             int x,y;
 88             scanf("%d%d",&x,&y);
 89             if(Max<x) Max=x,t=i+1;
 90             if(Min>x) Min=x,s=i+1;
 91         }
 92         for(int i=0; i<m; i++)
 93         {
 94             int u,v,w;
 95             scanf("%d%d%d",&u,&v,&w);
 96             add(u,v,w);
 97             add(v,u,w);
 98         }
 99         printf("%d\n",isap());
100     }
101     return 0;
102 }

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11391886.html