zoukankan      html  css  js  c++  java
  • zoj 2532(Internship )找割边

      题目大意就是给你n个城市,m个中转站,以及l条道路,l条道路描述了n个城市(编号为1到n),m个中转站(编号为n+1到n+m)和总中心(视为编号为0的点)的边关系,然后问你增加哪条边的容量可以增加总中心接受到的数据量。

    首先设总中心0为超级汇点et(因为它接受信息),然后设个超级源点st(N+M+1),超级源点就是发出数据的点,因为题目说了每个城市可以看作有无限的数据要发送,所以将每个城市和源点连起来,容量为inf。然后很明显这题就是要找割边,我的理解是割边就是流量满了即残留已经为0的边,并且从st可以到这条边的一个点,从et可以到这条边的另外一个点,那么给这条边增加容量就可以 增大最大流了。做法就是先跑个dinic,目的是得到在最大流情况下的残量网络,然后在此基础上从st往et方向dfs,标记从st点出发能到的点,接着从et往st方向dfs,标记从et点出发能到的点,最后遍历每个正边判断一下是否是割边即可。

    这题我因为没有给en初始化,每次交都Segmentation Fault,心累,最后还是逐个语句排除才找到的bug

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    #define inf 0x3f3f3f3f
    struct edge
    {
        int u,v,cap,nxt;
    }e[5500];
    int head[500],depth[500],vis1[500],vis2[500],cur[500],ans[5000],que[500];
    int n,m,l,st,et,en;
    void addedge(int u,int v,int c)
    {
        e[en].u=u;
        e[en].v=v;
        e[en].cap=c;
        e[en].nxt=head[u];
        head[u]=en++;
        e[en].u=v;
        e[en].v=u;
        e[en].cap=0;
        e[en].nxt=head[v];
        head[v]=en++;
    }
    bool bfs()
    {
        int fron,rear;
        fron=rear=0;
        for(int i=et;i<=st;i++)
            depth[i]=0;
        depth[st]=1;
        que[rear++]=st;
        while(fron!=rear)
        {
            int u=que[fron++];
            for(int i=head[u];i!=-1;i=e[i].nxt)
            {
                if(e[i].cap&&!depth[e[i].v])
                {
                    depth[e[i].v]=depth[u]+1;
                    que[rear++]=e[i].v;
                }
            }
        }
        return depth[et]!=0;
    
    }
    int dfs(int u,int f)
    {
        if(u==et) return f;
        for(int&i=cur[u];i!=-1;i=e[i].nxt)
        {
            if((depth[e[i].v]==depth[u]+1)&&e[i].cap)
            {
                int ff=dfs(e[i].v,min(f,e[i].cap));
                if(ff>0)
                {
                    e[i].cap-=ff;
                    e[i^1].cap+=ff;
                    return ff;
                }
            }
        }
        return 0;
    }
    void dinic()
    {
        int maxflow=0;
        while(bfs())
        {
            for(int i=et;i<=st;i++)
                cur[i]=head[i];
            int tmp;
            while(tmp=dfs(st,inf))
                maxflow+=tmp;
    
    
        }
    }
    void dfs1(int u)
    {
        vis1[u]=1;
        for(int i=head[u];i!=-1;i=e[i].nxt)
        {
            int v=e[i].v;
            if(!vis1[v]&&e[i].cap)
                dfs1(v);
        }
    }
    void dfs2(int u)
    {
        vis2[u]=1;
        for(int i=head[u];i!=-1;i=e[i].nxt)
        {
            if(!vis2[e[i^1].u]&&e[i^1].cap)
                dfs2(e[i^1].u);
    
        }
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        while(1)
        {
            cin>>n;
            if(!n) break;
            cin>>m>>l;
            et=0;
            st=n+m+1;
            for(int i=et;i<=st;i++)
                head[i]=-1;
            en=0;
            for(int i=1;i<=l;i++)//建图
            {
                int uu,vv,cc;
                cin>>uu>>vv>>cc;
                addedge(uu,vv,cc);
            }
            for(int i=1;i<=n;i++)//将源点和每个城市相连,不用对汇点操作,因为汇点才输入的时候就操作完了
                addedge(st,i,inf);
            dinic();
            memset(vis1,0,sizeof(vis1));
            memset(vis2,0,sizeof(vis2));
            dfs1(st);
            dfs2(et);
            int k=0;
            for(int i=0;i<en;i+=2)
            {
                int u=e[i].u;
                int v=e[i].v;
                int c=e[i].cap;
                if((vis1[u]==1)&&(vis2[v]==1)&&(c==0))
                    ans[k++]=i/2+1;
    
            }
            if(k==0)
                cout<<endl;
            else
            {
                cout<<ans[0];
                for(int i=1;i<k;i++)
                    cout<<" "<<ans[i];
                cout<<endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Spark SQL 编程API入门系列之SparkSQL数据源
    [转]Window2008站点安全设置,IIS7/IIS7.5中目录执行权限的设置方法
    [转]c# 对密码执行散列和 salt 运算方法
    [转]C#使用 Salt + Hash 来为密码加密
    [转]webservice 采用SSL实现加密传输
    [转]如何借助 TLS/SSL 确保套接字连接的安全(使用 C#/VB/C++ 和 XAML 的 Windows 应用商店应用)
    [转]网银在线支付接口和应用
    [转]支付宝接口程序、文档及解读(ASP.NET)
    [转]加盐hash保存密码的正确方式
    [转]如何安全的存储密码
  • 原文地址:https://www.cnblogs.com/eason9906/p/11755016.html
Copyright © 2011-2022 走看看