codevs1033 蚯蚓的游戏问题 裸最小费用最大流,注意要拆点
因为蚯蚓走过的路径不能重合,所以把每个点拆成两个点,容量赋为1,保证不会走过相同的点,再加超级源点(程序中为1)和一个辅助点(程序中为2)容量赋为k来控制蚯蚓的数量,最后汇集到一个超级汇点上。做一遍最小费用最大流即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 struct charge{ 7 int u,v,cost,c,next; 8 }f[50000]; 9 int n,m,k,num=2,cnt=0,point[3003],q[50000],pre[3003],dist[3003]; 10 bool vis[3003]; 11 void insect(int x,int y,int co,int bei) 12 { 13 f[cnt].u=x;f[cnt].v=y;f[cnt].cost=bei;f[cnt].c=co; 14 f[cnt].next=point[x];point[x]=cnt++; 15 f[cnt].u=y;f[cnt].v=x;f[cnt].cost=-bei;f[cnt].c=0; 16 f[cnt].next=point[y];point[y]=cnt++; 17 } 18 bool spfa(int begin,int end) 19 { 20 int mp,a,b,head=0,tail=0; 21 memset(q,0,sizeof(q)); 22 memset(pre,0xff,sizeof(pre)); 23 memset(dist,0x7f,sizeof(dist)); 24 memset(vis,0,sizeof(vis)); 25 q[0]=begin; dist[begin]=0; vis[begin]=1; 26 while (head<=tail) 27 { 28 a=q[head]; 29 vis[a]=0; 30 mp=point[a]; 31 while (mp>=0) 32 { 33 if (f[mp].c>0){ 34 b=f[mp].v; 35 if (dist[b]>dist[a]+f[mp].cost) 36 { 37 dist[b]=dist[a]+f[mp].cost; 38 pre[b]=mp; 39 if (!vis[b]){vis[b]=1;tail++;q[tail]=b;} 40 } 41 } 42 mp=f[mp].next; 43 } 44 head++; 45 } 46 return dist[end]!=2139062143; 47 } 48 int MCMF(int begin,int end) 49 { 50 int ans=0,mp,i,flow,flowsum=0; 51 while (spfa(begin,end)) 52 { 53 flow=2139062143; 54 for (i=pre[end];i!=-1;i=pre[f[i].u]) 55 if (f[i].c<flow) flow=f[i].c; 56 for (i=pre[end];i!=-1;i=pre[f[i].u]) 57 { 58 f[i].c-=flow; 59 f[i^1].c+=flow; 60 } 61 ans+=dist[end]; 62 flowsum+=flow; 63 } 64 return ans; 65 } 66 int main() 67 { 68 scanf("%d %d %d\n",&n,&m,&k); 69 int i,a,b,c,j,ff; 70 memset(point,0xff,sizeof(point)); 71 insect(1,2,k,0); 72 for (i=1;i<=m;++i) 73 { 74 scanf("%d",&c); num+=2; 75 insect(2,num-1,1,0); insect(num-1,num,1,-c); 76 } 77 ff=4; 78 for (i=2;i<=n;++i) 79 { 80 for (j=1;j<=m+i-1;++j) 81 { 82 scanf("%d",&c); num+=2; 83 if (j>1) insect(ff-2,num-1,1,0); 84 if (j<m+i-1) insect(ff,num-1,1,0); 85 insect(num-1,num,1,-c); 86 ff+=2; 87 } 88 ff=num+2-(m+i-1)*2; 89 } 90 for (i=1;i<=m+n-1;++i) 91 insect(num-(m+n-1)*2+i*2,num+1,1,0); 92 num++; 93 printf("%d\n",-1*MCMF(1,num)); 94 return 0; 95 }
NOI 2017 Bless All
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步