最大流——Luogu2762 [网络流24题]太空飞行计划问题
2017-05-25 10:21
465 查看
题面:Luogu2762
网络流24题之二
最大权闭合子图 ,首先建图
我们先从源点向每个实验连上权值为实验收益的边,再从每个器材向汇点权值为配置费用的边
然后每对配对方案连一条权值为INF的边
跑最小割即可,答案就是实验收益总和-最大流
具体证明不证了
两个比较容易炸的地方:
读入:挺恶心的因为并没有告诉你到底配对的方案数有多少,请不要使用类似读入优化的读入方式(我试过好像这对于换行符不敏感。。。),推荐字符串getline读入后处理
输出方案:首先找器材,我们可以试着把器材到汇点的边删去再跑最小割(放心,这题n<=50 m<=50 是T不掉的)然后对比答案如果后者答案少的就是权值那么说明这条边满流,器材可用,继而实验也可以推出来了
网络流24题之二
最大权闭合子图 ,首先建图
我们先从源点向每个实验连上权值为实验收益的边,再从每个器材向汇点权值为配置费用的边
然后每对配对方案连一条权值为INF的边
跑最小割即可,答案就是实验收益总和-最大流
具体证明不证了
两个比较容易炸的地方:
读入:挺恶心的因为并没有告诉你到底配对的方案数有多少,请不要使用类似读入优化的读入方式(我试过好像这对于换行符不敏感。。。),推荐字符串getline读入后处理
输出方案:首先找器材,我们可以试着把器材到汇点的边删去再跑最小割(放心,这题n<=50 m<=50 是T不掉的)然后对比答案如果后者答案少的就是权值那么说明这条边满流,器材可用,继而实验也可以推出来了
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #include<cstdlib> #include<string> #include<ctime> #include<queue> #include<climits> using namespace std; string ctrmmp;//请忽视这个变量名……读入专用 bool an[10001]; int dist[10001],cur[10001],n,m,s,t,sum=0,v[100001]; int nedge=-1,p[100001],c[100001],C[100001],nex[100001],head[100001]; inline void addedge(int x,int y,int z){ p[++nedge]=y;C[nedge]=c[nedge]=z; nex[nedge]=head[x];head[x]=nedge; } inline bool bfs(int s,int t){ queue<int>q;q.push(s); memset(dist,-1,sizeof dist);dist[s]=1; while(!q.empty()){ int now=q.front();q.pop(); for(int k=head[now];k>-1;k=nex[k])if(c[k]&&dist[p[k]]==-1){ dist[p[k]]=dist[now]+1;q.push(p[k]); } } return dist[t]>-1?1:0; } inline int dfs(int x,int low){ if(x==t)return low; int a,used=0; for(int k=cur[x];k>-1;k=nex[k])if(c[k]&&dist[p[k]]==dist[x]+1){ a=dfs(p[k],min(c[k],low-used)); if(a)c[k]-=a,c[k^1]+=a,used+=a; if(c[k])cur[x]=k; if(used==low)break; } if(!used)dist[x]=-1; return used; } inline int dinic(){ int flow=0; while(bfs(s,t)){ for(int i=s;i<=t;i++)cur[i]=head[i]; flow+=dfs(s,1e9); } return flow; } int main() { memset(p,-1,sizeof p);memset(nex,-1,sizeof nex); memset(c,-1,sizeof c);memset(head,-1,sizeof head); scanf("%d%d",&n,&m); s=0;t=n+m+1; for(int i=1;i<=n;i++){ int v;scanf("%d",&v);addedge(s,i,v);addedge(i,s,0);sum+=v; getline(cin,ctrmmp);ctrmmp+=' ';int l=ctrmmp.size(); int k=0; for(int j=0;j<l;j++){ if(ctrmmp[j]>='0'&&ctrmmp[j]<='9')k=k*10+ctrmmp[j]-'0'; else if(k)addedge(i,n+k,1e9),addedge(n+k,i,0),k=0; }//读入 } for(int i=1;i<=m;i++){ int x;scanf("%d",&x); addedge(n+i,t,x);addedge(t,n+i,0); } int ans=dinic(); for(int k=head[t];k>-1;k=nex[k]){ memcpy(c,C,sizeof(C)); int rp=c[k^1];c[k^1]=0; if(ans-dinic()==rp)an[p[k]-n]=1; }//记录器材是否可行 for(int i=1;i<=n;i++){ bool flag=1; for(int k=head[i];k>-1;k=nex[k])if(p[k]&&!an[p[k]-n]){flag=0;break;} if(flag)printf("%d ",i); }//记录实验是否可行 puts("");for(int i=1;i<=m;i++)if(an[i])printf("%d ",i); printf("\n%d",sum-ans); return 0; }
相关文章推荐
- 网络流24题 太空飞行计划问题___最大权闭合子图
- 【网络流24题】 No.2 太空飞行计划问题 (最大闭合权图 最大流 )
- 【网络流24题】太空飞行计划问题
- [网络流24题][洛谷P2762]太空飞行计划问题
- 网络流24题2 太空飞行计划问题 洛谷 2762
- 【网络流24题】太空飞行计划问题(网络流)
- 线性规划与网络流24题 02太空飞行计划问题 最小割
- loj6001「网络流 24 题」太空飞行计划(最大权闭合图+最小割)
- 【网络流24题】太空飞行计划(最大权闭合图+最小割)
- LOJ 「网络流 24 题」太空飞行计划(最大权闭合子图)
- [网络流24题 #2]太空飞行计划问题
- 【网络流24题 太空飞行计划】最大权闭合子图
- Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)
- 【网络流二十四题 太空飞行计划问题】【最大权闭合图->最小割】
- [网络流24题] 02 太空飞行计划(最大权闭合图, 最大流)
- [网络流24题 #2]太空飞行计划问题
- 太空飞行计划问题(网络流24题,七)
- 【网络流24题】太空飞行计划问题
- 线性规划与网络流24题の2 太空飞行计划问题(最大权闭合图问题)
- loj6001「网络流 24 题」太空飞行计划 最小割(最大权闭合图复习)