bzoj1449/2895[JSOI2009]球队收益

真是道挺不错的题,构图很棒。 而且还是个双倍经验题23333,由截图可见,权限狗的题数据更好、

我觉得HZWER大神和硕神都讲得很好了,我也就继续偷懒了安静硕神的 hzwer's

分析可以参考硕神的,关于构图,我们要想清楚怎么拆边,细节不太多,挺好的题。

贴代码

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #include 
        
          #define Max 0x7fffffff #define me(a,x) memset(a,x,sizeof a) using namespace std; struct node { int x,y,c,d,next; }a[50100]; int len,first[6010]; void ins(int x,int y,int c,int d) { a[++len].x=x,a[len].y=y,a[len].c=c,a[len].d=d; a[len].next=first[x],first[x]=len; a[++len].x=y,a[len].y=x,a[len].c=0,a[len].d=-d; a[len].next=first[y],first[y]=len; } int d[6010],t,l[6010]; bool v[6010]; queue 
         
           q; bool spfa() { for(int i=0;i<=t;i++)l[i]=v[i]=0,d[i]=Max; v[0]=1,d[0]=0; q.push(0); while(!q.empty()) { int x=q.front(); for(int k=first[x];k;k=a[k].next) { int y=a[k].y; if(d[y]>d[x]+a[k].d && a[k].c) { d[y]=d[x]+a[k].d; l[y]=k; if(!v[y]){v[y]=1; q.push(y);} } } q.pop(); v[x]=0; } return d[t]!=Max; } int win[5010],lose[5010],c1[5010],c2[5010]; int in[5010]; int main() { int n,m,i,j,x,y; scanf("%d%d",&n,&m); t=n+m+1; for(i=1;i<=n;i++)scanf("%d%d%d%d",&win[i],&lose[i],&c1[i],&c2[i]); int ans=0; me(in,0); len=1; me(first,0); for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); in[x]++,in[y]++,lose[x]++,lose[y]++; ins(i,x+m,1,0),ins(i,y+m,1,0); ins(0,i,1,0); } for(i=1;i<=n;i++) ans+=c1[i]*win[i]*win[i]+c2[i]*lose[i]*lose[i]; for(i=1;i<=n;i++) for(j=1;j<=in[i];j++) { ins(i+m,t,1,c1[i]*(2*win[i]+1)+c2[i]*(-2*lose[i]+1)); win[i]++,lose[i]--; } while(spfa()) { for(i=l[t];i;i=l[a[i].x]) a[i].c--,a[i^1].c++; ans+=d[t]; } printf("%d\n",ans); return 0; } 
          
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值