gusfield

BZOJ2229

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
  
  int cnt,nd[151],dep[151],sor,tar,dl[151],cur[151],sta[10001],mark[151],a[151],n,ans[151][151],tmp[151],m;
  
  struct edge{
      int next,des,cap,fr;
  }sid[10001];
  
  void addedge2(int u,int v,int cap){
      sid[cnt].next=nd[u];sid[cnt].des=v;sid[cnt].cap=cap;nd[u]=cnt;sid[cnt].fr=u;cnt++;
      sid[cnt].next=nd[v];sid[cnt].des=u;sid[cnt].cap=cap;nd[v]=cnt;sid[cnt].fr=v;cnt++;
  }
   
   int bfs(){
      memset(dep,-1,sizeof(dep));
      
      int head=1,tail=1;
      dep[sor]=0;dl[head]=sor;
      while (head<=tail){
        for (int p=nd[dl[head]];p!=-1;p=sid[p].next)
          if ((dep[sid[p].des]==-1)&&(sid[p].cap)) dep[sid[p].des]=dep[dl[head]]+1,dl[++tail]=sid[p].des;
        head++;  
    }
    
    if (dep[tar]==-1) return(0);else return(1);
   }
  
    int dinic(){
      int maxflow=0;
      while (bfs()){
          for (int i=1;i<=n;i++) cur[i]=nd[i];
          
          int u=sor,top=0;
            while(1){
              if (u==tar){
                  int mi=1e9,last;
                  for (int i=1;i<=top;i++)
                    if (sid[sta[i]].cap<mi)
                    {mi=sid[sta[i]].cap;last=i;}
                    
                  for (int i=1;i<=top;i++) 
                  sid[sta[i]].cap-=mi,sid[sta[i]^1].cap+=mi;
                u=sid[sta[last]].fr;cur[u]=sid[cur[u]].next;top=last-1;
                maxflow+=mi;
                continue;
            }
            
            while((cur[u]!=-1)&&((sid[cur[u]].cap==0)||(dep[sid[cur[u]].des]!=dep[u]+1)))
              cur[u]=sid[cur[u]].next;
              
            if (cur[u]!=-1){sta[++top]=cur[u];u=sid[cur[u]].des;continue;}
            else{
                if (u==sor) break;
                dep[u]=-1;
                u=sid[sta[top--]].fr;
                continue;
            }       
          }
      }
      return(maxflow);
  }
  
  void restore(){
      for (int i=0;i<=cnt;i+=2)
      sid[i].cap=sid[i^1].cap=(sid[i].cap+sid[i^1].cap)>>1; 
  }

  void dfs(int po){
      mark[po]=1;
      for (int p=nd[po];p!=-1;p=sid[p].next)
        if (sid[p].cap&&!mark[sid[p].des])
          dfs(sid[p].des);
  }

  void solve(int l,int r){
      if (l==r) return;
      restore();
      sor=a[l];tar=a[r];
      int flow=dinic();
      
      for (int i=1;i<=n;i++) mark[i]=0;
      dfs(sor);
      for (int i=1;i<=n;i++) if (mark[i])
        for (int j=1;j<=n;j++) if (!mark[j])
          ans[i][j]=ans[j][i]=min(ans[i][j],flow);
      int pol=l-1,por=r+1;
    for (int i=l;i<=r;i++)         
      if (mark[a[i]]) tmp[++pol]=a[i];else tmp[--por]=a[i];
    for (int i=l;i<=r;i++) a[i]=tmp[i];
    solve(l,pol);solve(por,r);  
  }

  int main(){      
      int T;
      scanf("%d",&T);
      while (T--){
        scanf("%d%d",&n,&m);cnt=0;
      for (int i=1;i<=n;i++) nd[i]=-1,a[i]=i;
      for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)
        ans[i][j]=1e9;
      for (int i=1;i<=m;i++){
          int t1,t2,t3;
          scanf("%d%d%d",&t1,&t2,&t3);
          addedge2(t1,t2,t3);
      }
      solve(1,n);
      int q;
      scanf("%d",&q);
      while (q--){
          int lim,tans=0;
          scanf("%d",&lim);
          for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++)
            if (ans[i][j]<=lim) tans++;
          printf("%d",tans);if (q!=0||T!=0) printf("
");
      }
      if (T!=0) printf("
");
    }
  }
原文地址:https://www.cnblogs.com/zhujiangning/p/6358774.html