zoukankan      html  css  js  c++  java
  • hdu3917 最大权闭合图

    题意:有N个城市,M个公司。现在需要建立交通是获得的利益最大。如果2个公司A,B, A修的路为Xa->Ya,B的路为Xb->Yb,如果Ya==Xb,那么这2个公司有关系。

    对于每个公司都有获得的税,和需要付出的价值。求最大能够得到的利润为多少。

    分析:

    很明显是最小权闭合图。最大获利=总共的值-(付出的值+没得到的值)。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define INF 99999999
    using namespace std;
    const int maxn = 6500;
    struct node
    {
        int to;
        int v;
        int flag;
        int next;
    }edge[maxn*maxn/2];
    struct company
    {
        int x;
        int y;
        int t;
        int z;
    }temp[3100];
    int index,pre[maxn],S,T,vis[maxn];
    int val[5050],fv[5050];
    int min(int x,int y){return x<y?x:y;}
    void add(int x,int y,int z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].flag=index+1;
        edge[index].next=pre[x];
        pre[x]=index++;
        edge[index].to=x;
        edge[index].v=0;
        edge[index].flag=index-1;
        edge[index].next=pre[y];
        pre[y]=index++;
    }
    int dfs(int u,int low)
    {
        int i,used=0;
        if(u==T)
            return low;
        for(i=pre[u];i!=-1&&used<low;i=edge[i].next)
        {
            if(edge[i].v>0&&vis[edge[i].to]==vis[u]+1)
            {
                int a=dfs(edge[i].to,min(edge[i].v,low-used));
                edge[i].v-=a;
                edge[edge[i].flag].v+=a;
                used+=a;
            }
        }
        if(!used)
            vis[u]=-1;
        return used;
    }
    bool BFS()
    {
        int i;
        queue<int>q;
        memset(vis,-1,sizeof(vis));
        vis[0]=1;
        q.push(0);
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            for(i=pre[t];i!=-1;i=edge[i].next)
            {
                if(edge[i].v&&vis[edge[i].to]<0)
                {
                    vis[edge[i].to]=vis[t]+1;
                    q.push(edge[i].to);
                }
            }
        }
        if(vis[T]>0)
            return true;
        return false;
    }
    int main()
    {
        int n,m,i,j,k;
        while(~scanf("%d%d",&n,&m))
        {
            if(!n&&!m)
                break;
            int sum=0;
            index=1;
            memset(pre,-1,sizeof(pre));
            memset(fv,0,sizeof(fv));
            for(i=1;i<=m;i++)
            {
                scanf("%d",&val[i]);
            }
            scanf("%d",&k);
            for(i=1;i<=k;i++)
            {
                scanf("%d%d%d%d",&temp[i].x,&temp[i].y,&temp[i].t,&temp[i].z);
                val[temp[i].t]-=temp[i].z;
            }
            for(i=1;i<=m;i++)
            {
                if(val[i]<0)
                    add(i,m+1,-val[i]);
                else
                {
                    sum+=val[i];
                    add(0,i,val[i]);
                }
            }
            for(i=1;i<=k;i++)
            {
                for(j=1;j<=k;j++)
                {
                    if(i==j)continue;
                    if(temp[i].y==temp[j].x)
                    {
                        if(temp[i].t!=temp[j].t)
                        {
                            add(temp[i].t,temp[j].t,INF);
                        }
                    }
                }
            }
            int ans=0;
            S=0,T=m+1;
            while(BFS())
            {
                int a=dfs(0,INF);
                if(!a)break;
                ans+=a;
            }
            printf("%d
    ",sum-ans);
        }
    }
  • 相关阅读:
    第七届湘计算机程序设计竞赛的学生 报道称,数字游戏
    python IDE
    字符串处理
    Ajax得知(两)—— 一个简单的Ajax示例
    九度OJ 1068 球半径和数量 (模拟)
    centos 之7zip
    svnclient本地化和异常处理
    java web.xml listener servlet 和filter加载顺序
    Jquery zTree实例
    探索Android中的Parcel机制(上)
  • 原文地址:https://www.cnblogs.com/sweat123/p/4920788.html
Copyright © 2011-2022 走看看