[网络流24题] 数字梯形问题
2018-02-19 21:29
477 查看
题面:
传送门
思路:
三合一题目
但是实际上做好了第一个就没有别的问题了
第一问:
把每个数字拆成两个点,中间连一条容量为1,费用为0的边,以此达到限制每个点流量的目的
然后其余的不多说,源点到第一层,每一层向下连,最后一层到汇点
第二问:
第一问中每个点内部的那条边容量改成inf就好
第三问:
直接dp算了......当然你也可以再改改边,跑网络流,不过估计没有dp快
Code:
传送门
思路:
三合一题目
但是实际上做好了第一个就没有别的问题了
第一问:
把每个数字拆成两个点,中间连一条容量为1,费用为0的边,以此达到限制每个点流量的目的
然后其余的不多说,源点到第一层,每一层向下连,最后一层到汇点
第二问:
第一问中每个点内部的那条边容量改成inf就好
第三问:
直接dp算了......当然你也可以再改改边,跑网络流,不过估计没有dp快
Code:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define inf 1000000000 using namespace std; inline int read(){ int re=0,flag=1;char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') flag=-1; ch=getchar(); } while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar(); return re; } int n,m,cnt,ans,flow,tot,first[10010],x[25][25],id[25][25]; int dis[10010],pre[10010],path[10010]; struct edge{ int to,next,w,cap; }a[100010]; inline void add(int u,int v,int w,int cap){ // cout<<"add "<<u<<ends<<v<<ends<<w<<ends<<cap<<endl; a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt; a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt; } void init(){ memset(first,-1,sizeof(first)); memset(a,0,sizeof(a));cnt=-1;ans=0;flow=0; } int spfa(int s,int t){ int q[10010],head=0,tail=1,maxn=10000,i,u,v,w; memset(pre,-1,sizeof(pre)); for(i=s;i<=t;i++) dis[i]=inf; q[0]=s;dis[s]=0; while(head!=tail){ u=q[head];head=(head+1)%maxn; // cout<<"spfa "<<u<<endl; for(i=first[u];~i;i=a[i].next){ v=a[i].to;w=a[i].w; // cout<<" to "<<v<<ends<<dis[v]<<ends<<w+dis[u]<<endl; if(a[i].cap&&dis[v]>dis[u]+w){ dis[v]=dis[u]+w; pre[v]=u;path[v]=i; q[tail]=v;tail=(tail+1)%maxn; } } } return ~pre[t]; } inline int _min(int l,int r){return (l<r)?l:r;} int mcmf(int s,int t){ int f,u; while(spfa(s,t)){ f=inf; for(u=t;u!=s;u=pre[u]) f=_min(f,a[path[u]].cap); flow+=f;ans+=dis[t]*f; // cout<<"mcmf "<<flow<<ends<<ans<<endl; for(u=t;u!=s;u=pre[u]){ a[path[u]].cap-=f; a[path[u]^1].cap+=f; } } } int main(){ freopen("digit.in","r",stdin); freopen("digit.out","w",stdout); int i,j; n=read();m=read(); for(i=1;i<=m;i++){ for(j=1;j<=i+n-1;j++) x[i][j]=read(),id[i][j]=++tot; } //T1 init(); for(i=1;i<=n;i++) add(0,id[1][i],0,1); for(i=1;i<=m;i++){ for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,1); } for(i=1;i<m;i++){ for(j=1;j<=i+n-1;j++){ add(id[i][j]+tot,id[i+1][j],-x[i][j],1); add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1); } } for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],1); mcmf(0,(tot<<1)+1); printf("%d\n",-ans); //T2 init(); for(i=1;i<=n;i++) add(0,id[1][i],0,1); for(i=1;i<=m;i++){ for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf); } for(i=1;i<m;i++){ for(j=1;j<=i+n-1;j++){ add(id[i][j]+tot,id[i+1][j],-x[i][j],1); add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1); } } for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf); mcmf(0,(tot<<1)+1); printf("%d\n",-ans); //T3 init(); for(i=1;i<=n;i++) add(0,id[1][i],0,1); for(i=1;i<=m;i++){ for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf); } for(i=1;i<m;i++){ for(j=1;j<=i+n-1;j++){ add(id[i][j]+tot,id[i+1][j],-x[i][j],inf); add(id[i][j]+tot,id[i+1][j+1],-x[i][j],inf); } } for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf); mcmf(0,(tot<<1)+1); printf("%d",-ans); }
相关文章推荐
- [网络流24题]数字梯形问题
- 网络流24题 -No.16 数字梯形问题
- 线性规划与网络流24题之数字梯形问题 最大权不相交路径
- 【网络流24题-16】数字梯形问题
- 【网络流24题】数字梯形问题
- 【网络流24题】No.16 数字梯形问题 (不相交路径 最大费用流)
- 线性规划与网络流24——数字梯形问题
- 【网络流24题-16】数字梯形问题 费用流
- [网络流24题 #16]数字梯形问题
- LOJ6010 「网络流 24 题 - 11」数字梯形 坠大费用坠大流 坠大权不相交路径
- COGS738 [网络流24题] 数字梯形(最小费用最大流)
- 【网络流24题】数字梯形(二分图+最大费用流)
- [网络流24题] 数字梯形
- 数字梯形问题[网络流24题之16]
- 网络流24题16. 数字梯形问题
- 网络流16数字梯形问题
- 【网络流24题】数字梯形(费用流)
- 网络流16数字梯形问题
- Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)
- loj6010「网络流 24 题」数字梯形