hdu6126 Give out candies(SPFA+Dinic)
来源:互联网 发布:wps不能使用数据透视表 编辑:程序博客网 时间:2024/06/13 14:56
题意:有n个小朋友,标号为1到n,你要给每个小朋友至少1个且至多m个的糖果。小朋友们共提出k个要求,每个要求包括三个整数x,y,z,表示x号小朋友得到的糖果数减去y号小朋友得到的糖果数不大于z。如果你给i号小朋友j颗糖果,他会获得w[i][j]的满意度,你需要最大化所有小朋友的满意度之和。
官方题解:用i.j这点表示给第i个孩子至少j块糖,当这个点属于S集合时所代表条件成立。然后i.j->i.j+1连1000-wi,j,i.m向T连1000-wi,m,S向i.1连inf。如果存在ax-ay>=z,x.k->y.k+z连inf。跑最小割,再用n*1000减掉答案。
想法:直接按上述方法建图跑最小割,但是在此之前应使用SPFA判定K个限制关系是否会构成负环(即无解,输出-1)。
#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<iostream>#include<algorithm>#include<queue>#include<stack>#include<set>#include<map>#include<deque>#include<vector>#include<functional>using namespace std;#define LL long long#define mm(a,b) memset(a,b,sizeof(a))const double eps=1.0e-6;const double PI=acos(-1.0);template<typename T>T gcd(T a,T b){return b==0?a:gcd(b,a%b);}template<typename T>T lcm(T a,T b){return a/gcd(a,b)*b;}template<typename T>T _abs(T a){return a>0?a:-a;}typedef pair<int,int> P;const int maxn=2555;const int INF=1<<30;//Dinicstruct edge{ int w,to,next;}ed[20000];int head[maxn],cnt,dis[maxn];void add(int x,int y,int z){ ed[cnt].to=y; ed[cnt].w=z; ed[cnt].next=head[x]; head[x]=cnt++; ed[cnt].to=x; ed[cnt].w=0; ed[cnt].next=head[y]; head[y]=cnt++;}bool bfs(int s,int t){ memset(dis,0,sizeof(dis)); dis[s]=1; int q[maxn],iq=0; q[iq++]=s; int i,k,top; for(i=0;i<iq;i++) { top=q[i]; if(top==t) return true; for(k=head[top];k!=-1;k=ed[k].next) if(!dis[ed[k].to]&&ed[k].w) { q[iq++]=ed[k].to; dis[ed[k].to]=dis[top]+1; } } return false;}int dfs(int now,int maxw,int t){ if(now==t) return maxw; int ret=0,aug,k; for(k=head[now];k!=-1;k=ed[k].next) if(ed[k].w&&dis[ed[k].to]==dis[now]+1) { aug=dfs(ed[k].to,min(maxw-ret,ed[k].w),t); ed[k].w-=aug; ed[k^1].w+=aug; ret+=aug; if(ret==maxw) return ret; } return ret;}int Dinic(int s,int t){ int ans=0; while(bfs(s,t)) ans+=dfs(s,INF,t); return ans;}//SPFAstruct edge2{ int to,w,next;}e[maxn];int cnt2;int d[maxn],head2[maxn];bool visit[maxn];bool vis[maxn];int outque[maxn];void add2(int x,int y,int z){ e[cnt2].to=y; e[cnt2].w=z; e[cnt2].next=head2[x]; head2[x]=cnt2++;}bool spfa(int s,int n){ int k,top; mm(visit,0); mm(outque,0); fill(d,d+n+1,INF); queue<int> q; q.push(s); visit[s]=true; d[s]=0; vis[s]=1; while(q.size()) { top=q.front(); q.pop(); visit[top]=false; if(++outque[top]>n+1) return false; for(k=head2[top];k!=-1;k=e[k].next) if(d[e[k].to]>e[k].w+d[top]) { d[e[k].to]=e[k].w+d[top]; if(!visit[e[k].to]) { visit[e[k].to]=true; vis[e[k].to]=1; q.push(e[k].to); } } } return true;}int xx[222],yy[222],zz[222];//记录小朋友们的要求int main(){ int n,m,t,k,x; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); cnt=0; mm(head,-1); for(int i=1;i<=n;i++) { add(0,(i-1)*m+1,INF); for(int j=1;j<=m;j++) { scanf("%d",&x); add((i-1)*m+j,j==m?n*m+1:(i-1)*m+j+1,1000-x); } } cnt2=0; mm(head2,-1); mm(vis,0); for(int i=0;i<k;i++) { scanf("%d%d%d",&xx[i],&yy[i],&zz[i]); add2(xx[i],yy[i],zz[i]); } bool f=1; for(int i=1;i<=n;i++) if(!vis[i])//可能构成多个连通块,对每个连通块都应判断是否有负环 if(!spfa(i,n)) { f=0; break; } if(!f) { puts("-1"); continue; } for(int i=0;i<k;i++) { for(int j=1;j<=m;j++) { if(zz[i]>=0&&j+zz[i]<=m) add((xx[i]-1)*m+j+zz[i],(yy[i]-1)*m+j,INF); else if(zz[i]<0&&j-zz[i]<=m)//官方题解的一个坑,最好还是为每个小朋友分配m+1个点,第m+1个点再连汇点 add((xx[i]-1)*m+j,j-zz[i]!=m?(yy[i]-1)*m+j-zz[i]:n*m+1,INF); } } int ans=Dinic(0,n*m+1); printf("%d\n",1000*n-ans); } return 0;}/*13 3 31 2 31 2 31 2 31 2 -12 3 -13 1 -1*/
阅读全文
0 0
- hdu6126 Give out candies(SPFA+Dinic)
- HDU 6126 Give out candies(最小割-Dinic)
- [HDU 6126] Give out candies
- HDU-6126 Give out candies(最小割)
- HDU 6126 Give out candies(最小割)
- HDU 6126 Give out candies 最小割
- HDU 6126 Give out candies (贼巧妙的最小割)
- 3159 Candies SPFA
- poj3159 Candies(SPFA+stack)
- Candies SPFA + 栈
- HDU 3416 spfa + dinic
- poj 3159 Candies (spfa+栈)
- poj 3159 Candies(差分约束 spfa stack实现)
- cf——Candies——(spfa)
- poj——3159——Candies(spfa)
- POJ 3159 Candies(SPFA+栈)差分约束
- POJ 3159 Candies(spfa最短路,差分约束)
- POJ 3159 Candies(差分约束+SPFA )
- poj 1679 The Unique MST (次小生成树)
- 【Firefox os】【kaios】创建一个ipdl
- 深度学习框架caffe及py-faster-rcnn详细配置安装过程
- Guava(七)外面很多坏银地
- AvaudioPlayer
- hdu6126 Give out candies(SPFA+Dinic)
- Docker命令详解
- 成为优秀算法工程师的唯一条件
- SQL的基本曾删改查
- 拓扑排序
- 大数据string八进制转为string十六进制(通过string的二进制)
- caffe框架下目标检测——faster-rcnn实战篇操作
- [RK3288][Android7.1.2] Launcher3 源码阅读之step4:详解Launcher的OnCreate方法的C部分
- Linux Qt调用 LibVLC记录