【2017"百度之星"程序设计大赛 - 初赛(B)】度度熊的交易计划
【链接】点击打开链接
【题意】
在这里写题意
【题解】
先设一个超级源点,向每个片区都建一条边,容量为b,费用为-a;
然后从每个片区再连一条边,指向一个超级汇点.
容量为d,费用为c;
然后从起点到汇点跑一下最大费用流就好.
(把spfa的最短路改成最长路就是最大费用流了);
这个费用流,在求只会出现正数的费用的时候是不用考虑那么多的.
显然我们这里是有负数的
所以有可能到了某个时刻,增广路得到的费用为负数,这个时候,我们就不能继续按照这条路卖东西了.
这意味着我们继续走的话,会亏本.
所以虽然还没得到最大流,也应该停手了.
只能按照之前的方案得到最大利润了,不能再继续做增广路了。
也就是说,有一些题目,在得到最大流之前,就可能已经得到最优的方案了.
(有负数的情况下);
【错的次数】
1
【反思】
边的个数一定要看清楚啊。
要记得你加了双向边。
【代码】
#include <bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define mp make_pair #define pb push_back #define fi first #define se second #define ms(x,y) memset(x,y,sizeof x) #define ri(x) scanf("%d",&x) #define rl(x) scanf("%lld",&x) #define rs(x) scanf("%s",x) #define oi(x) printf("%d",x) #define ol(x) printf("%lld",x) #define oc putchar(' ') #define os(x) printf(x) #define all(x) x.begin(),x.end() #define Open() freopen("F:\\rush.txt","r",stdin) #define Close() ios::sync_with_stdio(0) typedef pair<int,int> pii; typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1}; const int dy[9] = {0,0,0,-1,1,-1,1,-1,1}; const double pi = acos(-1.0); const int N = 500; const int NN = 1000 + 4000; const int INF = 0x3f3f3f3f; struct abc{ int from,en,flow,nex,cost; }; int n,m,totm,fir[N+50],dis[N+50],pre[N+50],mi[N+50],ans; abc bian[NN+100]; bool inq[N+50]; queue <int> dl; void add(int x,int y,int flow,int cost){ bian[totm].nex = fir[x]; fir[x] = totm; bian[totm].from = x; bian[totm].en = y; bian[totm].cost = cost; bian[totm].flow = flow; totm++; bian[totm].nex = fir[y]; fir[y] = totm; bian[totm].from = y; bian[totm].en = x; bian[totm].cost = -cost; bian[totm].flow = 0; totm++; } bool spfa(int s,int t){ ms(dis,-INF),ms(inq,0),ms(mi,INF); dis[s] = 0,inq[s] = 1; dl.push(s); pre[t] = -1; while (!dl.empty()){ int x = dl.front(); inq[x] = false; dl.pop(); for (int i = fir[x];i!=-1;i = bian[i].nex){ int y = bian[i].en; if (bian[i].flow && dis[y] < dis[x] + bian[i].cost){ dis[y] = dis[x] + bian[i].cost; mi[y] = min(bian[i].flow,mi[x]); pre[y] = i; if (!inq[y]){ inq[y] = true; dl.push(y); } } } } if (dis[t] < 0) return false; int now = t; while (now != s){ int temp = pre[now]; bian[temp].flow -= mi[t]; bian[temp^1].flow += mi[t]; now = bian[temp].from; } ans += dis[t]*mi[t]; return true; } int main(){ //Open(); //Close(); while (~ri(n)){ ri(m); ans = 0; totm = 0; ms(fir,255); rep1(i,1,n){ int a,b,c,d; ri(a),ri(b),ri(c),ri(d); add(0,i,b,-a); add(i,n+1,d,c); } rep1(i,1,m){ int x,y,k; ri(x),ri(y),ri(k); add(x,y,INF,-k); add(y,x,INF,-k); } while (spfa(0,n+1)); oi(ans);puts(""); } return 0; }