zoukankan      html  css  js  c++  java
  • HDU 5352 MZL's City

    最小费用最大流,因为要控制字典序,网络流控制不好了...一直WA,所以用了费用流,时间早的费用大,时间晚的费用少。

    构图:

    建立一个超级源点和超级汇点。超级源点连向1操作,容量为K,费用为COST,然后COST-1,因为下一次遇到1操作,费用为减少1,即COST-1;

    每个1操作连向当前能建造的城市,容量为1,费用为0;

    每个城市连向汇点,容量为1,费用为0;

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    //设置节点数量
    const int maxn=1000+10;
    
    const int INF=0x7FFFFFFF;
    struct Edge
    {
        int from,to,cap,flow,cost;
    };
    int N,M,K,len,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    int inq[maxn];
    int d[maxn];
    int p[maxn];
    int a[maxn];
    int use[maxn];
    int dis[maxn][maxn];
    
    void init()
    {
        for(int i=0; i<maxn; i++) G[i].clear();
        edges.clear();
    }
    
    void Addedge(int from,int to,int cap,int cost)
    {
        edges.push_back((Edge)
        {
            from,to,cap,0,cost
        });
        edges.push_back((Edge)
        {
            to,from,0,0,-cost
        });
        len=edges.size();
        G[from].push_back(len-2);
        G[to].push_back(len-1);
    }
    
    bool BellmanFord(int s,int t,int &flow,int &cost)
    {
    
        for(int i=0; i<maxn; i++) d[i]=INF;
    
        memset(inq,0,sizeof(inq));
        memset(p,-1,sizeof(p));
    
        d[s]=0;
        inq[s]=1;
        p[s]=0;
        a[s]=INF;
    
        queue<int>Q;
        Q.push(s);
        while(!Q.empty())
        {
            int u=Q.front();
            Q.pop();
            inq[u]=0;
            for(int i=0; i<G[u].size(); i++)
            {
                Edge& e=edges[G[u][i]];
                if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
                {
                    d[e.to]=d[u]+e.cost;
                    p[e.to]=G[u][i];
                    a[e.to]=min(a[u],e.cap-e.flow);
                    if(!inq[e.to])
                    {
                        Q.push(e.to);
                        inq[e.to]=1;
                    }
                }
            }
        }
        if(d[t]==INF) return false;
        flow+=a[t];
        cost+=d[t]*a[t];
        int u=t;
        while(u!=s)
        {
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
            u=edges[p[u]].from;
        }
        return true;
    }
    
    void Mincost (int s,int t)
    {
        int flow=0,cost=0;
        while(BellmanFord(s,t,flow,cost));
        printf("%d
    ",flow);
        // printf("最小费用:%d
    ",cost);
    }
    
    void dfs(int x)
    {
        use[x]=1;
        for(int i=1; i<=N; i++)
        {
            if(use[i]==0&&dis[i][x])
                dfs(i);
        }
    }
    
    int main()
    {
        int TT;
        scanf("%d",&TT);
        while(TT--)
        {
            scanf("%d%d%d",&N,&M,&K);
            //n个节点,m条边
            init();//初始化
            s=0;
            t=N+1;//设置源点和汇点
            memset(dis,0,sizeof(dis));
            int tt=N+2;
            for(int i=1; i<=N; i++) Addedge(i,t,1,0);
            int COST=M+10;
            for(int i=0; i<M; i++)
            {
                int x;
                scanf("%d",&x);
                if(x==1)
                {
                    int e;
                    memset(use,0,sizeof(use));
                    scanf("%d",&e);
                    Addedge(s,tt,K,COST);
                    COST--;
                    dfs(e);
                    for(int ii=1; ii<=N; ii++)
                        if(use[ii])
                            Addedge(tt,ii,1,0);
                    tt++;
                }
                else if(x==2)
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    dis[l][r]=1;
                    dis[r][l]=1;
                }
                else
                {
                    int e;
                    scanf("%d",&e);
                    while(e--)
                    {
                        int l,r;
                        scanf("%d%d",&l,&r);
                        dis[l][r]=0;
                        dis[r][l]=0;
                    }
                }
            }
            Mincost(s,t);
            int flag=0;
            for(int i=0; i<edges.size(); i++)
            {
                if(flag==0&&edges[i].from==s)
                {
                    printf("%d",edges[i].flow);
                    flag=1;
                }
                else if(edges[i].from==s)
                    printf(" %d",edges[i].flow);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    优秀JS学习站点
    一些比较好的论坛、博客
    最全前端问题及答案总结[转]
    EDM制作要点
    前端技术-调试工具(下)
    前端技术-调试工具(上)
    smartJQueryZoom(smartZoom) 的使用方法
    修改博客园日历的默认样式
    smartJQueryZoom(smartZoom) 存在的兼容性BUG,以及解决方法
    javascript实战 : 简单的颜色渐变
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4703680.html
Copyright © 2011-2022 走看看