日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 3605Escape(缩点+网络流之最大流)

發(fā)布時間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 3605Escape(缩点+网络流之最大流) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3605

本來打算昨天寫兩道題的,結(jié)果這個題卡住了,最后才發(fā)現(xiàn)是最后的推斷條件出錯了,推斷滿流的條件應該是與n的比較,居然寫成與全部星球總?cè)萘康谋容^了。(近期大腦短路。。)

這題也不是全然自己想的,沒想到縮點這一技巧,由于n的數(shù)據(jù)范圍太大,普通的建圖方法會超時超內(nèi)存,須要縮點,由于對于每一個點來說,一共僅僅有2^10種方法,而最多一共同擁有10W個點,顯然有非常多點是反復的,這時能夠採取縮點的方法,將反復的當成一個點來處理。這樣數(shù)據(jù)范圍就縮小到了1024個點,速度大大提升。

建圖思路是建一源點與匯點,將每種方法與源點相連,權(quán)值為這樣的方法反復的次數(shù),將每一個星球與匯點相連,權(quán)值為每一個星球的最大容量,再將每種方法與星球相連,權(quán)值為INF,最后推斷是否滿流。

代碼例如以下:

#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <algorithm>using namespace std; const int INF=1e9; int head[2000], s, t, nv, n, cnt; int num[2000], d[2000], pre[2000], cur[2000], q[2000], fei[2000]; struct node {int u, v, next, cap; }edge[1000000]; void add(int u, int v, int cap) {edge[cnt].v=v;edge[cnt].cap=cap;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].v=u;edge[cnt].cap=0;edge[cnt].next=head[v];head[v]=cnt++; } void bfs() {memset(num,0,sizeof(num));memset(d,-1,sizeof(d));int f1=0, f2=0, i;q[f1++]=t;d[t]=0;num[0]=1;while(f1>=f2){int u=q[f2++];for(i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(d[v]==-1){d[v]=d[u]+1;num[d[v]]++;q[f1++]=v;}}} } int isap() {memcpy(cur,head,sizeof(cur));int flow=0, i, u=pre[s]=s;bfs();while(d[s]<nv){if(u==t){int f=INF, pos;for(i=s;i!=t;i=edge[cur[i]].v){if(f>edge[cur[i]].cap){f=edge[cur[i]].cap;pos=i;}}for(i=s;i!=t;i=edge[cur[i]].v){edge[cur[i]].cap-=f;edge[cur[i]^1].cap+=f;}flow+=f;if(flow>=n)return flow;u=pos;}for(i=cur[u];i!=-1;i=edge[i].next){if(d[edge[i].v]+1==d[u]&&edge[i].cap){break;}}if(i!=-1){cur[u]=i;pre[edge[i].v]=u;u=edge[i].v;}else{if(--num[d[u]]==0) break;int mind=nv;for(i=head[u];i!=-1;i=edge[i].next){if(mind>d[edge[i].v]&&edge[i].cap){mind=d[edge[i].v];cur[u]=i;}}d[u]=mind+1;num[d[u]]++;u=pre[u];}}return flow; } int main() {int m, x, i, j, top, y, z, num, a[20];while(scanf("%d%d",&n,&m)!=EOF){memset(head,-1,sizeof(head));memset(fei,0,sizeof(fei));cnt=0;s=0;top=0;num=0;for(i=1;i<=n;i++){x=0;for(j=1;j<=m;j++){scanf("%d",&y);x=x*2+y;}fei[x]++;}for(i=1;i<=1100;i++){if(fei[i]){num++;}}t=num+m+1;nv=t+1;for(i=1;i<=1100;i++){if(fei[i]){//printf("--%d %d\n", i, fei[i]);top++;add(s,top,fei[i]);x=i;z=m+1;while(x){y=x%2;z--;if(y){add(top,z+num,INF);}//printf("--%d %d %d %d--",y, top, z, num);x=x/2;}//printf("\n");}}for(i=1;i<=m;i++){scanf("%d",&x);add(i+num,t,x);}x=isap();if(x>=n)printf("YES\n");elseprintf("NO\n");}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/gcczhongduan/p/4296425.html

總結(jié)

以上是生活随笔為你收集整理的HDU 3605Escape(缩点+网络流之最大流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。