• bzoj1449: [JSOI2009]球队收益


    类似于修车那道题的思维。拆点。手画一下比较容易出来。。。YY能力不可靠啊~~~

     #include<cstdio>
     #include<cstring>
     #include<iostream>
     #include<algorithm>
     #include<queue>
     using namespace std;
     #define rep(i,n) for(int i=1;i<=n;i++)
     #define clr(x,c) memset(x,c,sizeof(x))
     #define REP(i,s,t) for(int i=s;i<=t;i++)
     #define qwq(x) for(edge *o=head[x];o;o=o->next)
     #define op() clr(head,0);pt=edges;
     int read(){
     	int x=0;char c=getchar();
     	while(!isdigit(c)) c=getchar();
     	while(isdigit(c)) x=x*10+c-'0',c=getchar();
     	return x;
     } 
     const int nmax=6005;
     const int maxn=2000000;
     const int inf=0x7f7f7f7f;
     struct edge{
     	int to,cap,cost;edge *next,*rev;
     };
     edge edges[maxn],*pt,*head[nmax],*p[nmax];
     int d[nmax],a[nmax],c[nmax],dd[nmax],win[nmax],lose[nmax],cnt[nmax];
     bool inq[nmax];
     void add(int u,int v,int d,int w){
     	pt->to=v;pt->cap=d;pt->cost=w;pt->next=head[u];head[u]=pt++;
     }
     void adde(int u,int v,int d,int w){
     	add(u,v,d,w);add(v,u,0,-w);head[u]->rev=head[v];head[v]->rev=head[u];
     }
     int mincost(int s,int t){
     	int cost=0;
     	while(1){
     		clr(d,0x7f);clr(inq,0);inq[s]=1;d[s]=0;a[s]=inf;
    		queue<int>q;q.push(s);
    		while(!q.empty()){
    			int x=q.front();q.pop();inq[x]=0;
    			qwq(x) if(o->cap>0&&d[o->to]>d[x]+o->cost){
    				int to=o->to;d[to]=d[x]+o->cost;
    				a[to]=min(a[x],o->cap);p[to]=o;
    				if(!inq[to]) q.push(to),inq[to]=1;
    			}
    		}
    		if(d[t]==inf) break;
    		cost+=d[t]*a[t];
    		int x=t;
    		while(x!=s) p[x]->cap-=a[t],p[x]->rev->cap+=a[t],x=p[x]->rev->to;
     	}
     	return cost;
     }
     int main(){
     	int n=read(),m=read(),u,v,s=0,t=n+m+1;
     	op();clr(cnt,0);int ans=0;
     	rep(i,n) win[i]=read(),lose[i]=read(),c[i]=read(),dd[i]=read();
     	rep(i,m) u=read(),v=read(),cnt[u]++,cnt[v]++,adde(s,i,1,0),adde(i,u+m,1,0),adde(i,v+m,1,0);
     	rep(i,n){
     		lose[i]+=cnt[i];
     		ans+=c[i]*win[i]*win[i]+dd[i]*lose[i]*lose[i];
     		rep(j,cnt[i]){
     			adde(i+m,t,1,2*(c[i]*win[i]-dd[i]*lose[i])+c[i]+dd[i]);
     			win[i]++;lose[i]--;
     		}
     	}
     	/*REP(i,0,n+m+1){
     		qwq(i) printf("%d ",o->to);printf("
    ");
     	}*/
     	printf("%d
    ",ans+mincost(s,t));
     	return 0;
     }
    

      

    1449: [JSOI2009]球队收益

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 702  Solved: 403
    [Submit][Status][Discuss]

    Description

    Input

    Output

    一个整数表示联盟里所有球队收益之和的最小值。

    Sample Input

    3 3
    1 0 2 1
    1 1 10 1
    0 1 3 3
    1 2
    2 3
    3 1

    Sample Output

    43

    HINT

    Source

     
    [Submit][Status][Discuss]
  • 相关阅读:
    程序猿初出茅庐之一:学习方法
    Winform实现鼠标可穿透的窗体镂空效果
    HashMap源码分析(上)
    Java Integer常量池——IntegerCache内部类
    find the Nth highest salary(寻找第N高薪水)
    分布式理论:深入浅出Paxos算法
    smash:一个类unix内核
    【官网翻译】如何在VSCode中使用代码片段功能(snippets)?
    JavaScript与魔数检测
    给你一个团队,你能怎么管-读后感-凝聚力和执行力(1)
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5662469.html
Copyright © 2020-2023  润新知