zoukankan      html  css  js  c++  java
  • 追查坏牛奶(最大流)

    进入今天的正题,追查坏牛奶

    思想的话不会人家的玄学求最小割的边数,于是自己想了个神奇的乱搞,先求出最大流,即最小割,然后枚举每条边看是否完全属于割集,然后将其永久去掉

    然后将整个输出即可

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=100010;
    const ll INF=0x7ffffffff;
    ll m,n,s,t,pre[N],head[N],cnt=1,last[N],dep[N],tot,sum[N],ans,Ans,ff;
    struct edge
    { ll from,to,nx,flow;} e[N];
    struct node
    { ll x,y,z;} kk[N];
    void add_edge(ll from,ll to,ll flow)
    { cnt++;e[cnt].from=from;e[cnt].flow=flow;
      e[cnt].nx=head[from];e[cnt].to=to;head[from]=cnt;
      cnt++;e[cnt].flow=0;e[cnt].to=from;
      e[cnt].from=to;e[cnt].nx=head[to];head[to]=cnt;
    }
    bool bfs(int s,int t)
    { memset(dep,0,sizeof(dep));
      queue<ll> que;dep[s]=1;que.push(s);
      while (!que.empty())
      { ll x=que.front();que.pop();
        for (ll i=head[x];i;i=e[i].nx)
        { ll y=e[i].to;
          if (dep[y]==0&&e[i].flow>0)
          { dep[y]=dep[x]+1;
            que.push(y);
          }
        }
      }
     if (dep[t]==0) return false;
     else return true;  
    }
    ll dfs(int x,ll limit,int t)
    { if(x==t) return limit;
      ll used=0;
      for (ll i=head[x];i;i=e[i].nx)
      { ll y=e[i].to;
        if (dep[y]==dep[x]+1&&e[i].flow>0)
        { ll di=dfs(y,min(limit-used,e[i].flow),t);
          if (di>0)
          { e[i].flow-=di;
            e[i^1].flow+=di;
            used+=di;
            if (used==limit) return used;
          }
        }
      }
     if (!used) dep[x]=-2;
     return used; 
    }
    void dinic()
    { while (bfs(1,n)) ans+=dfs(1,INF,n);}
    void cs()
    {  ans=0;cnt=1;memset(head,0,sizeof(head));
       for (int j=1;j<=m;j++) add_edge(kk[j].x,kk[j].y,kk[j].z);
       for (int k=1;k<=tot;k++) {e[sum[k]*2].flow=0;} 
    }
    int main()
    { 
      scanf("%lld%lld",&n,&m);
      for (ll i=1;i<=m;i++)
      { ll x,y,z;
        scanf("%lld%lld%lld",&x,&y,&z);
        kk[i].x=x;kk[i].y=y;kk[i].z=z;
        add_edge(x,y,z);
      }
      dinic();ff=ans;Ans=ans;
      for (int i=1;i<=m;i++)
      { cs();
        ll f=e[i*2].flow;
        e[i*2].flow=0;
        dinic();
        if (ans==0&&f==ff) {tot=1;sum[tot]=i;break;}
        if (ans+f==Ans) {tot++;sum[tot]=i;Ans=ans;}
      }
      printf("%lld %lld ",ff,tot);
      for (int i=1;i<=tot;i++)
      printf("%lld ",sum[i]);
      return 0;
    }
    慢即是快,细则是能,于小处铸迤逦
  • 相关阅读:
    HTML 页面的 批量删除的按钮
    HTML 选择器
    ....
    java 反射机制
    插件库
    向上滚动
    浮动元素定位float
    中文字体对应的英文名称
    echarts入门教程
    ie9浏览器window.openbug
  • 原文地址:https://www.cnblogs.com/Hale522520/p/10623572.html
Copyright © 2011-2022 走看看