首页 > 代码库 > 太空飞行计划 网络流
太空飞行计划 网络流
经典的最大权闭合子图问题;
这种问题的求解思路是:
建图:将s连边向权值为正的点,通过依赖关系连接权值为正的点和权值为负的点,权值为负的点连边向t;
求c=最小割,a=所有权值为正的节点权值和,ans=a-c;
证明过程网上是有的;
用dinic敲的,但是用的还不熟练;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<ctime> 7 #include<algorithm> 8 using namespace std; 9 const int maxn=200;10 const int inf=1000000000;11 const int s=0,t=120;12 struct node{13 int y,next,flow,re;14 }e[maxn*10];15 int linkk[maxn],len=0,n,m,g[maxn][maxn],cnt[maxn],w[maxn],sum=0;16 void print(int x){printf("%d\n",x);}17 void print(int x,int y){printf("%d %d\n",x,y);}18 void insert(int x,int y,int flow){19 e[++len].y=y;e[len].flow=flow;20 e[len].next=linkk[x];linkk[x]=len;e[len].re=len+1;21 e[++len].y=x;e[len].flow=0;22 e[len].next=linkk[y];linkk[y]=len;e[len].re=len-1;23 }24 bool flag=0;25 int read(){26 int x=0;char ch=getchar();27 while(ch<‘0‘||ch>‘9‘)ch=getchar();28 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}29 if(ch==‘\n‘)flag=1;30 return x;31 }32 void init(){33 scanf("%d%d",&n,&m);34 int v;35 for(int i=1;i<=n;i++){36 scanf("%d",&v);insert(s,i,v);37 flag=0;sum+=v;38 while(!flag){cnt[i]++;g[i][cnt[i]]=read();}39 }40 for(int i=1;i<=m;i++)scanf("%d",&w[i]);41 for(int i=1;i<=n;i++)42 for(int j=1;j<=cnt[i];j++)43 insert(i,g[i][j]+n,inf);44 for(int i=1;i<=m;i++)insert(i+n,t,w[i]);45 }46 int q[maxn],tail=0,level[maxn],head=0;47 bool bfs(){48 memset(level,-1,sizeof(level));49 head=0;tail=0;level[s]=1;q[++tail]=s;50 while(++head<=tail){51 int x=q[head];52 for(int i=linkk[x];i;i=e[i].next){53 if(level[e[i].y]==-1&&e[i].flow){54 q[++tail]=e[i].y;55 level[e[i].y]=level[x]+1;56 }57 }58 }59 return level[t]>0;60 }61 int find(int x,int flow){62 if(x==t)return flow;63 int maxflow=0,d=0;64 for(int i=linkk[x];i&&maxflow<flow;i=e[i].next){65 if(level[e[i].y]==level[x]+1&&e[i].flow){66 if(d=find(e[i].y,min(flow-maxflow,e[i].flow))){67 maxflow+=d;68 e[i].flow-=d;69 e[e[i].re].flow+=d;70 }71 }72 }73 if(!maxflow)level[x]=-1;74 return maxflow;75 }76 void work(){77 int d=0,ans=0;78 while(bfs())79 while(d=find(s,inf))80 ans+=d;81 cout<<sum-ans<<endl;82 }83 int main(){84 //freopen("1.in","r",stdin);85 //freopen("1.out","w",stdout);86 init();87 work();88 }
太空飞行计划 网络流
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。