zoukankan      html  css  js  c++  java
  • zoj 2676 dinic模板求实型最小割(可做dinic模板)

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<queue>
    #include<math.h>
    using namespace std;
    #define eps 1e-6
    #define inf 0x3fffffff
    #define N 410
    struct node
    {
        int u,v,next;
        double w;
    }bian[N*4],f[N];
    int yong,head[N],dis[N],work[N];
    void init()
    {
        yong=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,double w)
    {
        bian[yong].v=v;
        bian[yong].w=w;
        bian[yong].next=head[u];
        head[u]=yong++;
    }
    int bfs(int S,int T)
    {
        queue<int>q;
        memset(dis,-1,sizeof(dis));
        dis[S]=0;
        q.push(S);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i!=-1;i=bian[i].next)
            {
                int v=bian[i].v;
                if(bian[i].w>0&&dis[v]==-1)
                {
                    dis[v]=dis[u]+1;
                    if(v==T)
                        return 1;
                    q.push(v);
                }
            }
        }
        return 0;
    }
    double dfs(int S,double a,int T)
    {
        if(S==T)return a;
        for(int &i=work[S];i!=-1;i=bian[i].next)
        {
            int v=bian[i].v;
            if(bian[i].w>0&&dis[v]==dis[S]+1)
            {
                double tt=dfs(v,min(a,bian[i].w),T);
                if(tt>0)
                {
                    bian[i].w-=tt;
                    bian[i^1].w+=tt;
                    return tt;
                }
            }
        }
        return 0;
    }
    double Dinic(int S,int T)
    {
        double ans=0;
        while(bfs(S,T))
        {
            memcpy(work,head,sizeof(head));
            while(1) {
            double tt=dfs(S,inf,T);//割出来的可能是负值
             if(tt<eps)break;
                ans+=tt;
            }
        }
        return ans;
    }
    int a[N],len,vis[N];
    void dfss(int u) {
      int i;
      // printf("%d
    ",u);
      for(i=head[u];i!=-1;i=bian[i].next) {
        int v=bian[i].v;
        if(bian[i].w>eps&&!vis[v]) {
            vis[v]=1;
            dfss(v);
        }
      }
    }
    int main()
    {
        int n,m,i;
        double st,en,mid,flow;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(i=1; i<=m; i++)
                scanf("%d%d%lf",&f[i].u,&f[i].v,&f[i].w);
            st=0;
            en=10000001;
            while(st<en+eps)
            {
                mid=(st+en)/2;
                init();
                flow=0;
                for(i=1; i<=m; i++)
                {
                 //   printf("%.2f %.2f
    ",f[i].w,mid);
                    if(f[i].w<mid+eps)
                        flow=flow+f[i].w-mid;
                    else
                    {
                        addedge(f[i].u,f[i].v,f[i].w-mid);
                        addedge(f[i].v,f[i].u,f[i].w-mid);
                    }
                }
                double k=Dinic(1,n);
                flow+=k;
          //  printf("%.2f
    ",k);
                if(flow>eps)
                    st=mid+eps;
                else
                    en=mid-eps;
            }
      //      printf("mid=%.10f
    ",mid);
            memset(vis,0,sizeof(vis));
            vis[1]=1;
            dfss(1);
            len=0;
                for(i=1;i<=m;i++) {
              //  printf("%.10f %.10f
    ",f[i].w,mid+eps);//&&vis[f[i].u]+vis[f[i].v]==1
                if(vis[f[i].u]+vis[f[i].v]==1||f[i].w<eps+mid)
                    len++;
                }
                printf("%d
    ",len);
                int ok=0;
                for(i=1;i<=m;i++)
                if(vis[f[i].u]+vis[f[i].v]==1||f[i].w<mid+eps) {
                        if(ok)
                        printf(" ");
                    printf("%d",i);
                ok=1;
                }
                printf("
    ");
                }
        return 0;
    }
    

  • 相关阅读:
    leetcode每日一题:836. 矩形重叠
    单链表之删除头结点,查找等于定值x的结点数,单链表的逆置
    拼数,零幺串
    最大公约数/最小公倍数
    寻找二叉树双亲结点
    Object类的派生-c++
    牛客小白月赛22
    二叉树的基本操作
    字符串的反转,替换,删除
    [2011山东ACM省赛] Identifiers(模拟)
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410560.html
Copyright © 2011-2022 走看看