诚哥的逆袭 sdoj

诚哥升入天堂之后,再次抛弃了世界,又找了n个妹子继续他天堂般的生活不过人渣诚的要求很高,他希望他选的妹子能给他带来最大的快乐已知每个妹子本身拥有一个消耗值ai,意思是人渣诚选了这个妹子就要消耗诚哥ai的精力。但如果人渣诚同时选了第i和第j个妹子,那么妹子我对妹子j就会对诚哥产生eij的精力值(j对i也会独立产生)。但如果人渣诚不选i和j,黄毛就会抢走这两个妹子,并给诚哥造成eij精力的损失现在人渣诚想得到最大的精力值,于是找到了你,并许诺你交流之后也让你过上好日子,你当然答应了这个差事,于是你写了一个程序...
网络流,建图比较难,其余随意

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define N 4000005
using namespace std;
long long sum[1005]={0};
long long first[10010];
long long nxt[N],h[10010];
struct node{
    long long u,v,w;
}e[N];
long long a[1005];
long long n;
long long ei[1005][1005];
long long st,ed;
long long cnt;
long long d[10010];
long long gap[10010];
void add(long long u,long long v,long long w){
    cnt++;
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].w=w;
    nxt[cnt]=first[u];
    first[u]=cnt;
}
void bfs(){//½øÐзֲã±êºÅ 
    //memset(d,-1,sizeof(d));// ½«dÊý×éÇåΪ-1£¬±¾Éí´ú±í·Ö²ãµÄ±àºÅ 
    queue<long long> q;//ÉèÒ»¸ö¶ÓÁÐ 
    d[ed]=1;//ÖÕµãµÄÉî¶ÈÊÇ1 
    gap[1]=1;
    q.push(ed);//½«ÖÕµã·ÅÈë¶ÓÁÐÄÚ 
    while(!q.empty()){//µ±¶ÓÁв»Îª¿ÕµÄʱºò£¬´ú±í»¹ÓеãµÄ²ãÊýÐèÒª¸üР
        long long u=q.front();q.pop();//½«¶ÓÊ×µÄÔªËØÈ¡³öÀ´£¬½øÐÐÔËËã 
        for(long long i=first[u];i;i=nxt[i]){//½øÐÐÇ°ÏòÐǵIJÙ×÷ 
            long long v=e[i].v;//°ÑÕâÌõ±ßµÄÖÕµãÈ¡³öÀ´ 
            if(!d[v]){//Èç¹ûÕâ¸öµã»¹Ã»ÓнøÐÐÉî¶È±àºÅ 
                d[v]=d[u]+1;//ÓÉÓÚ¶ÓÁеÄÐÔÖʱ£Ö¤ÁËÕâÌõ±ßÊÇ×îÇ°Ãæ·ÃÎʵ½µÄ 
                gap[d[v]]++;//ͬʱÕâÒ»²ãµÄµãÊýÒª+1 
                q.push(v);//½«Õâ¸öµã¼ÌÐø·Åµ½¶ÓÁÐÀïÈ¥ 
            }
        }
    }
}
long long dfs(long long st,long long ed,long long dat,long long now){//isapËã·¨×îÖØÒªµÄÒ»²½£¬st´ú±íͼÆðµã£¬ed´ú±íÖյ㣬dat´ú±íµ±Ç°µÄÁ÷´óС£¬ÅªÍêÊÇÖ¸ÏÖÔÚ¾­¹ýµÄµã 
    if(now==ed)return dat;//Èç¹ûÆðµãµÈÓÚÁËÖյ㣬ÒòΪdat´ú±íÉÏÃæÁ÷ÏòÕâ¸öµãµÄÁ÷´óС£¬µ½ÁË»ãµã²»¿ÉÒÔ¼ÌÐøÍùÏÂÁ÷£¬ËùÒÔÖ±½Ó·µ»Ø 
    long long nowdat=0;//ÏÖÔÚ´Óµ±Ç°µãÍùÏÂÁ÷µÄÁ÷Á¿³õʼ»¯Îª0 
    for(long long &i=first[now];i;i=nxt[i]){//»¹ÊÇÇ°ÏòÐǵIJÙ×÷£¬×¢ÒâÕâÀïÊÇ°´ÉîËѵÄ˳Ðò½øÐбéÀú 
        long long v=e[i].v;//½«Õâ¸ö±ßµÄÖÕµã¼Ç¼ÏÂÀ´ 
        if(d[v]==d[now]-1){//Èç¹ûµ±Ç°²ã²»Êǵ±Ç°µãµÄ²ãÊý¼õ1£¬Òâζ¸ü¼Ó¿¿½ü»ãµã£¬×¢ÒâÎÒÃÇÊÇ°´»ãµãÀ´½øÐзֲã±àºÅµÄ 
            long long nown=min(dat-nowdat,e[i].w);//ÏÖÔÚÎÒÃÇÒª·ÖÅäµ½µ±Ç°µãµÄÁ÷Á¿£¬ÏÔÈ»Õâ¸öµãÒý³öµÄÕâÒ»Ìõ±ßµÄÁ÷Á¿²»ÄÜ´óÓÚÊ£ÓàÁ÷Á¿»òÕßÕâÌõ±ßÔÊÐíµÄÁ÷Á¿ 
            nown=dfs(st,ed,nown,v);//wnÓÃÀ´¼Ç¼µ±Ç°µã¶ÔÓÚÕâÌõ±ßÍùϵÄÁ÷Á¿£¬¼Ì³ÐÊ£ÓàÁ÷Á¿ £¬½øÐеݹéÇóÏÂÒ»¸öµãÄÜÁ÷µÄ×î´óÁ÷ 
            nowdat+=nown;// Õâ¸öµãÍùϵÄ×ÜÁ÷Á¿¾ÍÊÇËùÓб߼ÓÆðÀ´µÄ×ÜºÍ  
            e[i].w-=nown;//ͬʱ£¬¸ù¾ÝÔö¹ã·ԭÀí£¬Õâ¸öµãµÄÁ÷Á¿ÒªÏàÓ¦µÄ¼õÉÙµ±Ç°Õâô¶à£¨ÒòΪÎÒÍùÏÂÁ÷ÁËÒ»²¿·Ö£¬Ò²Ðí»¹ÓÐÊ£Ó࣬ÓÃÀ´¼Ç¼£© 
            e[i^1].w+=nown;//ËüµÄ·´Ïò±ß¾ÍÒªÏàÓ¦µÄ¼ÓÉÏÕâô¶àµÄÁ÷Á¿ 
            if(dat==nowdat)return dat;//Èç¹ûµ±Ç°Á÷ÏÂÈ¥µÄÁ÷Á¿µÈÓÚ´ÓÉÏÃæÍùϵÄÁ÷Á¿£¬Ï൱ÓÚÈ«²¿´ÓÕâÌõ±ßÁ÷×ßÁË£¬ÒòΪÎÒÃÇÊÇ·µ»ØµÄ×î´óÖµ£¬ËùÒÔÖ±½Ó·µ»Ø 
        }
    }
    if(--gap[d[now]]==0){//µ±Ö´Ðе½ÕâÒ»²½Ê±£¬´ú±íÕâ¸öͼ¶ÏÁË 
        d[st]=n+3;// ÖÕÖ¹Ìõ¼þÊÇÆðµãµÄ²ãÊýÊÇn+1 
    }
    d[now]++;// 
    gap[d[now]]++;
first[now]=h[now];
    return nowdat;
}
long long isap(long long st,long long ed){
    long long ans=0;
    bfs();
    for(long long i=1;i<=n;i++)
        h[i]=first[i];
    h[st]=first[st];
    h[ed]=first[ed];
    while(d[st]<=n+2)
    {
        ans+=dfs(st,ed,1e17,st);
    }   
    return ans;
}
int main(){
    //freopen("employ15.in","r",stdin);
    //freopen("employ15.out","w",stdout);
    cin>>n;
    st=1001;
    ed=1002;
    cnt=1;
    for(long long i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        add(st,i,a[i]);
        add(i,st,0);
    }
    for(long long i=1;i<=n;i++){
        for(long long j=1;j<=n;j++){
            scanf("%lld",&ei[i][j]);
            sum[i]+=ei[i][j];
        }
    }
    for(long long i=1;i<=n;i++){
        add(i,ed,sum[i]);
        add(ed,i,0);
    }   
    for(long long i=1;i<=n;i++)
    {
        for(long long j=1;j<=n;j++)
            if(i!=j)
            {
                add(i,j,2*ei[i][j]);
                //cout<<2*ei[i][j]<<endl;
                add(j,i,0); 
            }
    }
    long long total=0;
    for(long long i=1;i<=n;i++)total+=sum[i];
    long long tempo=isap(st,ed);
    total-=tempo;
    cout<<total;
    return 0;
}

好像注释乱码了,随便看吧 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值