• hdu 2987最大权闭合图模板类型题


    /*
    最大权闭合图模板类型的题,考验对知识概念的理解。
    题意:现在要辞退一部分员工,辞退每一个员工可以的到一部分利益(可以是负的),并且辞退员工,必须辞退他的下属,求最大利益和辞退的最小人数。
    最大权闭合图模板类型。
    求出最大权后沿着源点s,dfs到的点就为最小的人数。
    证明/*
    转载:利用一个经典的trick:多关键字
    > 建图前,对所有b[i],执行变换b[i]=b[i]*10000-1,然后,会惊异地发现,
    > 此时最大流所对应的方案就是满足辞退最少人数的了。
    > 为什么?显然,变换后的流量r2除以10000后再取整就等于原来的流量,但是
    > r2的后四位却蕴含了辞退人数的信息:每多辞退一个人,流量就会少1。
    > 
    > 剩下的就是如何根据一个网络流输出方案。
    > 我的做法:从源点开始沿着残余网络dfs(只走没有满载的边),
    > 能dfs到的点对应的人就是需要辞退的。*/
    */
    #include"stdio.h"
    #include"string.h"
    #include"string"
    #include"queue"
    #define ll __int64
    #define N   9999
    #define inf 0x3fffffff
    using namespace std;
    struct node {
      ll u,v,w,next;
    }bian[N*50];
    ll fee[N];
    ll head[N],yong,s,t,dis[N];
    void init(){
    yong=0;
    memset(head,-1,sizeof(head));
    memset(dis,-1,sizeof(dis));
    }
    void addedge(ll u,ll v,ll w) {
    bian[yong].u=u;
    bian[yong].v=v;
    bian[yong].w=w;
    bian[yong].next=head[u];
    head[u]=yong++;
    }
    void add(ll u,ll v,ll w) {
    addedge(u,v,w);
    addedge(v,u,0);
    }
    void bfs() {
    ll u,v,i;
    queue<ll>q;
    q.push(t);
    dis[t]=0;
    while(!q.empty()) {
        u=q.front();
        q.pop();
        for(i=head[u];i!=-1;i=bian[i].next) {
            v=bian[i].v;
            if(dis[v]==-1) {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
    }
    return ;
    }
    ll ISAP() {
    ll sum=0;
    bfs();
    ll  gap[N],cur[N],stac[N],top,i;
    memset(gap,0,sizeof(gap));
    for(i=s;i<=t;i++) {
        gap[dis[i]]++;
        cur[i]=head[i];
    }
    ll k=s;
    top=0;
    while(dis[s]<t+1) {
         if(k==t) {
                ll minn=inf,index;
            for(i=0;i<top;i++) {
                ll e=stac[i];
                if(minn>bian[e].w) {
                    minn=bian[e].w;
                    index=i;
                }
            }
            for(i=0;i<top;i++) {
                ll e=stac[i];
                bian[e].w-=minn;
                bian[e^1].w+=minn;
            }
            sum+=minn;
            top=index;
            k=bian[stac[top]].u;
         }
         for(i=cur[k];i!=-1;i=bian[i].next) {
           ll  v=bian[i].v;
            if(bian[i].w&&dis[k]==dis[v]+1) {
                cur[k]=i;
                k=v;
                stac[top++]=i;
                break;
            }
         }
         if(i==-1) {
            ll m=t+1;
            for(i=head[k];i!=-1;i=bian[i].next)
                if(m>dis[bian[i].v]&&bian[i].w) {
                    m=dis[bian[i].v];
                    cur[k]=i;
                }
                if(--gap[dis[k]]==0)break;
                gap[dis[k]=m+1]++;
                if(k!=s)
                    k=bian[stac[--top]].u;
         }
    }
    return sum;
    }
    ll cou=0,vis[N];
    void dfs(ll u){//,ll pre) {会形成环越界
     ll i,j;
       cou++;
       vis[u]=1;
     for(i=head[u];i!=-1;i=bian[i].next) {
            j=bian[i].v;
        if(bian[i].w&&!vis[j]) {
            dfs(j);
        }
     }
     return ;
    }
    int main() {
         ll n,m,i,j,sum;
         while(scanf("%I64d%I64d",&n,&m)!=EOF) {
            init();
            s=0;t=n+1;sum=0;
            for(i=1;i<=n;i++) {
                scanf("%I64d",&fee[i]);
               if(fee[i]>0) {
                add(s,i,fee[i]);
                 sum+=fee[i];
               }
               else
                add(i,t,-fee[i]);
            }
            while(m--) {
                scanf("%I64d%I64d",&i,&j);
                add(i,j,inf);
            }
            cou=0;
            sum=sum-ISAP();
            memset(vis,0,sizeof(vis));
            dfs(0);
            printf("%I64d %I64d
    ",cou-1,sum);
         }
    return 0;
    }
    

  • 相关阅读:
    炒炒饼分锅喂
    奥运会
    360和腾讯QQ共存
    Lenovo F41 使用WinXP不能全屏看Flash格式的电影的解决方法
    如何在Windows server 2003上安装和设置Citrix MetaFrame XP FR3
    “电脑人才”是怎么炼成的
    Lenovo F41 使用WinXP不能全屏看Flash格式的电影的解决方法
    学车
    终于有了自己的本本了
    学车
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410652.html
Copyright © 2020-2023  润新知