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]
原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5662469.html