博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
费用流做题记录
阅读量:4658 次
发布时间:2019-06-09

本文共 6865 字,大约阅读时间需要 22 分钟。

BZOJ1221:

  trick:将每天用完的,和要用的分来开处理,避免花费的重叠计算,也就是拆点

#include
using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define ls i<<1#define rs ls | 1#define mid ((ll+rr)>>1)#define pii pair
#define MP make_pairtypedef long long LL;const long long INF = 1e18+1LL;const double Pi = acos(-1.0);const int N = 4e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e7;int na[N],ans,ans1,S,T,head[N],cnt = 1,n,dis[N],q[N],inq[N],from[N],f,fA,fB;struct { int from,to,next,c,v;}e[N * 2];void ins(int u,int v,int w,int c) { cnt++; e[cnt].from = u; e[cnt].to = v; e[cnt].v = w; e[cnt].c = c; e[cnt].next = head[u]; head[u] = cnt;}void insert(int u,int v,int w,int c) { ins(u,v,w,c);ins(v,u,0,-c);}int spfa() { for(int i = 0; i <= T; ++i) dis[i] = inf; int t = 0,w = 1; dis[S] = q[S] = S; inq[S] = 1; while(t!=w) { int now = q[t++]; if(t == 200001) t = 0; for(int i = head[now]; i; i = e[i].next) { if(e[i].v&&dis[e[i].to] > dis[now] + e[i].c) { from[e[i].to] = i; dis[e[i].to] = dis[now] + e[i].c; if(!inq[e[i].to]) { inq[e[i].to] = 1; q[w++] = e[i].to; if(w == 200001) w = 0; } } } inq[now] = 0; } if(dis[T] >= inf) return 0; return 1;}void mcf() { int i = from[T],x=inf; while(i) { x = min(e[i].v,x); i = from[e[i].from]; } i = from[T]; ans1 = x; while(i) { e[i].v -= x; e[i^1].v += x; ans += e[i].c*x; i = from[e[i].from]; }}int a,b;int main(){ cnt = 1; memset(head,0,sizeof(head)); scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fA,&fB); S = 0,T = 3*n; for(int i = 1; i <= n; ++i){ scanf("%d",&na[i]); insert(S,i,inf,0); insert(S,i+n,inf,f); insert(i+n,T,na[i],0); if(i + 1 <= n) insert(i,i+1,inf,0); if(i + a + 1 <= n) insert(i,n+i+a+1,inf,fA); if(i + b + 1 <= n) insert(i,n+i+b+1,inf,fB); } ans = 0,ans1 = 0; while(spfa()) mcf(); printf("%d\n",ans); return 0;}
BZOJ1221

 

BZOJ2424: [HAOI2010]订货:

    trick:拆点

#include
using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define ls i<<1#define rs ls | 1#define mid ((ll+rr)>>1)#define pii pair
#define MP make_pairtypedef long long LL;const long long INF = 1e18+1LL;const double Pi = acos(-1.0);const int N = 4e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e7;int ans,ans1,cnt,head[N],from[N],dis[N],inq[N],q[N],S,T;struct ss{ int from,to,next,c,v;}e[N * 2];void ins(int u,int v,int w,int c) { cnt++; e[cnt].from = u; e[cnt].to = v; e[cnt].v = w; e[cnt].c = c; e[cnt].next = head[u]; head[u] = cnt;}void insert(int u,int v,int w,int c) { ins(u,v,w,c);ins(v,u,0,-c);}int spfa() { for(int i = 0; i <= T; ++i) dis[i] = inf; int t = 0,w = 1; dis[S] = 0; q[t] = S; inq[S] = 1; while(t != w) { int now = q[t++]; if(t == 200001) t = 0; for(int i = head[now]; i; i = e[i].next){ if(e[i].v && dis[e[i].to] > dis[now] + e[i].c) { from[e[i].to] = i; dis[e[i].to] = dis[now] + e[i].c; if(!inq[e[i].to]) { inq[e[i].to] = 1; q[w++] = e[i].to; if(w == 200001) w = 0; } } } inq[now] = 0; } if(dis[T] >= inf) return 0; return 1;}void mcf() { int i = from[T],x = inf; while(i) { x = min(e[i].v, x); i = from[e[i].from]; } i = from[T]; ans1 = x; while(i) { e[i].v -= x; e[i^1].v += x; ans += e[i].c * x; i = from[e[i].from]; }}int n,m,s,x;int main() { cnt = 1; memset(head,0,sizeof(head)); scanf("%d%d%d",&n,&m,&s); T = 2*n+1,S = 0; for(int i = 1; i <= n; ++i) { scanf("%d",&x); insert(i+n,T,x,0); insert(i,i+n,inf,0); } for(int i = 1; i <= n; ++i) { scanf("%d",&x); insert(S,i,inf,x); if(i+1<=n)insert(i,i+1,s,m); } ans1 = 0,ans = 0; while(spfa()) mcf(); cout<
<
BZOJ2424

 

BZOJ3171: [Tjoi2013]循环格

 trick:每个点的入度 = 出度 = 1,所以,将每个点拆点

        S向每个点连容量1费用0的边

    每个点拆出的点向T连容量1,费用0的边

    每个格子向四周连费用0或1的边

 

HDU5988 

   trick:第一次走这条边的话,我们拆边就行了

     ans = 1 - 最大不能破坏概率

    不能破坏概率 = (1-p1)*(1-p2)*(……); ————》 2^(log2((1-p1)+log2(1-p2)+log2(……));

    基础费用流

    需要不能破坏概率最大,就将   -( log2((1-p1)+log2(1-p2)+log2(……) ) 求最小, 边费用 就放-log(1-p);就OK

#include
using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define ls i<<1#define rs ls | 1#define mid ((ll+rr)>>1)#define pii pair
#define MP make_pairtypedef long long LL;const long long INF = 1e18+1LL;const double Pi = acos(-1.0);const double eps = 0.000001;const int N = 6e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e9;int cnt,head[N],from[N],inq[N],q[N],S,T;double ans1,ans,dis[N];struct ss{ int from,to,next,v; double c;}e[N * 2];void ins(int u,int v,int w,double c) { cnt++; e[cnt].from = u; e[cnt].to = v; e[cnt].v = w; e[cnt].c = c; e[cnt].next = head[u]; head[u] = cnt;}void insert(int u,int v,int w,double c) { ins(u,v,w,c);ins(v,u,0,-c);}int spfa() { for(int i = 0; i <= T; ++i) dis[i] = 1.0*inf,from[i] = -1; int t = 0,w = 1; dis[S] = 0; from[S] = 0; q[t] = S; inq[S] = 1; while(t != w) { int now = q[t++]; for(int i = head[now]; i; i = e[i].next){ if(e[i].v && dis[e[i].to] - dis[now]-e[i].c> eps ) { from[e[i].to] = i; dis[e[i].to] = dis[now] + e[i].c; if(!inq[e[i].to]) { inq[e[i].to] = 1; q[w++] = e[i].to; } } } inq[now] = 0; } if(from[T] == -1) return 0; return 1;}void mcf() { int i = from[T],x = inf; while(i) { x = min(e[i].v, x); i = from[e[i].from]; } i = from[T]; while(i) { e[i].v -= x; e[i^1].v += x; ans += e[i].c*x; i = from[e[i].from]; }}int n,m,x,y,w,Ts;double p;int main() { scanf("%d",&Ts); while(Ts--) { scanf("%d%d",&n,&m); S = 0,T = n+1; cnt = 1; memset(head,0,sizeof(head)); for(int i = 1; i <= n; ++i) { scanf("%d%d",&x,&y); if(x > y)insert(S,i,x-y,0); if(y > x)insert(i,T,y-x,0); } for(int i = 1; i <= m; ++i) { scanf("%d%d%d%lf",&x,&y,&w,&p); if(w >= 1) insert(x,y,1,0); if(w > 1) insert(x,y,w-1,-log2(1-p)); } ans = 0; while(spfa()) mcf(); printf("%.2f\n",1-pow(2.0,-ans)); } return 0;}
HDU5988

 

转载于:https://www.cnblogs.com/zxhl/p/6832392.html

你可能感兴趣的文章
Makefile 工程管理
查看>>
笔记本键盘失灵怎么办? 笔记本电脑按键失灵的一般解决办法
查看>>
寻找最大的数
查看>>
【转】java中float与byte[]的互转 -- 不错
查看>>
sockaddr和sockaddr_in的区别
查看>>
基础练习1
查看>>
左旋转字符串
查看>>
第二次C语言实验报告
查看>>
XPath轴
查看>>
Struts2的优点与Struts1的区别:
查看>>
5-29 删除字符串中的子串
查看>>
webdriver模拟鼠标操作
查看>>
Spring cloud 基础
查看>>
游戏开发Unity渲染场景光照性能优化 ShaderLOD
查看>>
java中构造方法的使用
查看>>
使用Expression动态创建lambda表达式
查看>>
MapReduce
查看>>
找工作——JVM内存管理
查看>>
【Flask】在Flask中使用logger
查看>>
好系统重装助手教你如何让win10系统快速开机
查看>>