传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1449
题目简述:
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
题解:
设x为win,y为lose;
先让所有人后面比赛都会输,计算出一个preans,那么怎么处理会赢的请况呢?
很简单,就让一个人的win+1,lose-1,那么相对于之前就可以获得(c*(x+1)^2+d*(y-1)^2-c*x^2-d*y^2=2*c[i]*win[i]+c[i]+d[i]-2*d[i]*lose[i])
所以就在建一条这样的边就好了,推荐使用 zkw(速度快,代码短);
1 #include2 #include 3 #include 4 #define inf 0x7fffffff 5 #define maxn 1000000 6 int pre[maxn],v[maxn],cost[maxn],cap[maxn],lis[maxn]; 7 int lose[6010],win[6010],in[6010],c[6010],d[6010],dis[6010],now[6010],sla[6010],mark[6010]; 8 bool vis[6010]; 9 int n,m,s,t,tot,ans; 10 using namespace std; 11 void ins(int a, int b, int c, int d) 12 { 13 tot++; pre[tot]=now[a]; now[a]=tot; v[tot]=b; cost[tot]=d; cap[tot]=c; 14 } 15 void insert(int a, int b, int c, int d) 16 { 17 ins(a,b,c,d); ins(b,a,0,-d); 18 } 19 bool spfa() 20 { 21 int head=0,tail=1; 22 for (int i=s; i<=t; i++) dis[i]=inf; 23 memset(mark,0,sizeof(mark)); 24 lis[0]=t; dis[t]=0; mark[t]=1; 25 while (head!=tail) 26 { 27 int x=lis[head]; mark[x]=0; head++; 28 if(head==6005)head=0; 29 for (int i=now[x]; i; i=pre[i]) 30 { 31 if (dis[x]+cost[i^1]