zoukankan      html  css  js  c++  java
  • [ZJOI2011]最小割

    题解:

    以前看过,思维挺神奇的一道题目

    首先可以证明最小割是不能相交的

    那么我们就可以找到任意两点求一次最小割然后将割的两边分开来再递归这个过程

    另外最小割就是vis=0与vis=1之间的连边

    分治的时候把一个局部变量写了全局变量还有83??? 找个好久。。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 3000
    #define INF 1e9
    int dis[200][200],l,n,m,s,t;
    struct {
        int a,b,c,flow;
    }a[maxn*2],tmp[maxn*2];
    bool fz1[200],vis[200];
    int d[200],head[200];
    void arr(int x,int y,int z)
    {
        a[++l].a=head[x];
        a[l].b=y;
        a[l].c=z;
        a[l].flow=0;
        head[x]=l;
    }
    queue<int> q;
    bool bfs(){
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(s);
        d[s]=0; vis[s]=1;
        while (!q.empty())
        {
            int x=q.front();q.pop();
            int u=head[x];
            while (u)
            {
                int v=a[u].b;
                if (!vis[v]&&a[u].c>a[u].flow)
                {
                    vis[v]=1;
                    d[v]=d[x]+1;
                    q.push(v);
                }
                u=a[u].a;
            }
        }
        return(vis[t]);
    }
    int dfs(int x,int y)
    {
        if (x==t||y==0) return y;
        int flow=0,f,tmp;
        int u=head[x];
        while (u)
        {
            int v=a[u].b;
            if (d[x]+1==d[v]&&(f=dfs(v,min(y,a[u].c-a[u].flow)))>0)
            {
                a[u].flow+=f;
                if (u%2) tmp=u+1; else tmp=u-1;
                a[tmp].flow-=f;
                flow+=f; 
                y-=f;
                if (y==0) break;
            }
            u=a[u].a;
        }
        return(flow);
    }
    int maxflow()
    {
        int flow=0;
        while (bfs())
        {
            flow+=dfs(s,INF);
        }
        return(flow);
    }
    void get_ans(int ss,int tt)
    {
        for (int i=1;i<=l;i++) a[i].flow=0;
        bool tmp3[200],fz2[200];
        s=ss; t=tt;
        int ans=maxflow();
        memcpy(tmp3,vis,sizeof(vis));
        for (int i=1;i<=n;i++)
          if (vis[i])
            for (int j=1;j<=n;j++)
              if (!vis[j])
                dis[i][j]=min(dis[i][j],ans),dis[j][i]=min(ans,dis[j][i]);
        int tmp1=0,tmp2=0,num=0;
        for (int i=1;i<=n;i++)
          if (vis[i]&&fz1[i])
          {
              num++;
              if (!tmp1) tmp1=i; else tmp2=i;
          }
        memcpy(fz2,fz1,sizeof(fz1));
        for (int i=1;i<=n;i++)
          if (!vis[i]) fz1[i]=0;
        if (num>=2)
        {
        /*    l=0; memset(head,0,sizeof(head));
            for (int i=1;i<=m;i++)
              if (vis[tmp[i].a]&&vis[tmp[i].b]&&
                  fz1[tmp[i].a]&&fz1[tmp[i].b])
              {
                   arr(tmp[i].a,tmp[i].b,tmp[i].c);
                   arr(tmp[i].b,tmp[i].a,tmp[i].c);
              } */
             get_ans(tmp1,tmp2);
        }
        memcpy(vis,tmp3,sizeof(tmp3));
        memcpy(fz1,fz2,sizeof(fz2));
        tmp1=0,tmp2=0,num=0;
        for (int i=1;i<=n;i++)
          if (!vis[i]&&fz1[i])
          {
              num++;
              if (!tmp1) tmp1=i; else tmp2=i;
          }
        for (int i=1;i<=n;i++)
          if (vis[i]) fz1[i]=0;
        if (num>=2)
        {
        /*    l=0; memset(head,0,sizeof(head));
            for (int i=1;i<=m;i++)
              if (!vis[tmp[i].a]&&!vis[tmp[i].b]
              &&  fz1[tmp[i].a]&&fz1[tmp[i].b])
              {
                   arr(tmp[i].a,tmp[i].b,tmp[i].c);
                   arr(tmp[i].b,tmp[i].a,tmp[i].c);
              } */
            get_ans(tmp1,tmp2);
        }   
        memcpy(fz1,fz2,sizeof(fz2));
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        int T;
        cin>>T;
        for (int p=1;p<=T;p++)
        {
            
            l=0; memset(head,0,sizeof(head));
            memset(fz1,1,sizeof(fz1));
        cin>>n>>m;
        for (int i=1;i<=n;i++)
          for (int j=1;j<=n;j++) dis[i][j]=INF;
        for (int i=1;i<=m;i++)
        {
            int c,d,e;
            cin>>c>>d>>e;
            tmp[i].a=c; tmp[i].b=d; tmp[i].c=e;
            arr(c,d,e); arr(d,c,e);
        }
        get_ans(1,n);
        int q;
        cin>>q;
        int x;
        for (int i=1;i<=q;i++)
        {
            cin>>x;
            int ans=0;
            for (int j1=1;j1<=n;j1++)
              for (int j2=j1+1;j2<=n;j2++)
                if (dis[j1][j2]<=x||dis[j1][j2]==INF) ans++;
            cout<<ans<<endl;
        }
        cout<<endl;
    
        }
        return 0;
    }
  • 相关阅读:
    帝国cms 同个IP可提交一次
    帝国cms 图片相对路径绝对路径设置问题+帝国cms 手机端调用图片问题
    帝国CMS 手机版制作+帝国PC跳转到手机+重新定向
    帝国cms 相关问题
    简洁 清晰弹出层讲解制作(图片点击放大)
    webstorm 2016最新版破解+汉化
    ajax点击不断加载数据列表
    js中substr,substring,indexOf,lastIndexOf,split的用法
    Parallax.js|强大的javascript视觉差特效引擎
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8549318.html
Copyright © 2011-2022 走看看