[拆边费用流] BZOJ 1449 [JSOI2009]球队收益

来源:互联网 发布:java 退出程序 编辑:程序博客网 时间:2024/05/19 19:12

比较巧妙的是假设双方都输 然后输变赢增加的收益是多少 

跑费用流就好了


#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int M=100005,N=10005;struct edge{int u,v,f,w; int next;};edge G[M];int head[N],inum=1;inline void add(int u,int v,int f,int w,int p){G[p].u=u; G[p].v=v; G[p].f=f; G[p].w=w; G[p].next=head[u]; head[u]=p;}inline void link(int u,int v,int f,int w){add(u,v,f,w,++inum); add(v,u,0,-w,++inum);}const int NQ=N;int n,m,ans;int win[N],lose[N],a[N],b[N],c[N],d[N];int S,T,Mincost;int ins[N];int Q[NQ],l,r;int dis[N],pre[N];#define V G[p].vinline bool SPFA()  {      int u;      for (int i=1;i<=T;i++) dis[i]=1<<30,pre[i]=0,ins[i]=0;      memset(Q,0,sizeof(Q));      l=r=-1; Q[(++r)%NQ]=S; dis[S]=0; ins[S]=1;      while (l!=r)      {          u=Q[(++l)%NQ]; ins[u]=0;        for (int p=head[u];p;p=G[p].next)              if (G[p].f && dis[V]>dis[u]+G[p].w)              {                  dis[V]=dis[u]+G[p].w; pre[V]=p;                  if (!ins[V])                      Q[(++r)%NQ]=V,ins[V]=1;              }      }      if (dis[T]==1<<30) return false;      int minimum=1<<30;      for (int p=pre[T];p;p=pre[G[p].u])          minimum=min(minimum,G[p].f);      for (int p=pre[T];p;p=pre[G[p].u])      {          G[p].f-=minimum; G[p^1].f+=minimum;          Mincost+=G[p].w*minimum;    }      return true;  }  int main(){int tmp;freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(n); read(m);  S=n+m+1; T=S+1;for (int i=1;i<=n;i++)read(win[i]),read(lose[i]),read(c[i]),read(d[i]);  for (int i=1;i<=m;i++)read(a[i]),read(b[i]),lose[a[i]]++,lose[b[i]]++;  for (int i=1;i<=n;i++) ans+=c[i]*win[i]*win[i]+d[i]*lose[i]*lose[i];  for (int i=1;i<=m;i++)  {  link(S,i,1,0);link(i,a[i]+m,1,0);link(i,b[i]+m,1,0);  tmp=c[a[i]]*(2*win[a[i]]+1)-d[a[i]]*(2*lose[a[i]]-1);  link(a[i]+m,T,1,tmp);win[a[i]]++; lose[a[i]]--;  tmp=c[b[i]]*(2*win[b[i]]+1)-d[b[i]]*(2*lose[b[i]]-1);  link(b[i]+m,T,1,tmp);  win[b[i]]++; lose[b[i]]--;  }  while (SPFA());ans+=Mincost;printf("%d\n",ans);}


0 0
原创粉丝点击