题面:
思路:
三合一题目
但是实际上做好了第一个就没有别的问题了
第一问:
把每个数字拆成两个点,中间连一条容量为1,费用为0的边,以此达到限制每个点流量的目的
然后其余的不多说,源点到第一层,每一层向下连,最后一层到汇点
第二问:
第一问中每个点内部的那条边容量改成inf就好
第三问:
直接dp算了......当然你也可以再改改边,跑网络流,不过估计没有dp快
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define inf 1000000000 6 using namespace std; 7 inline int read(){ 8 int re=0,flag=1;char ch=getchar(); 9 while(ch>‘9‘||ch<‘0‘){ 10 if(ch==‘-‘) flag=-1; 11 ch=getchar(); 12 } 13 while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar(); 14 return re; 15 } 16 int n,m,cnt,ans,flow,tot,first[10010],x[25][25],id[25][25]; 17 int dis[10010],pre[10010],path[10010]; 18 struct edge{ 19 int to,next,w,cap; 20 }a[100010]; 21 inline void add(int u,int v,int w,int cap){ 22 // cout<<"add "<<u<<ends<<v<<ends<<w<<ends<<cap<<endl; 23 a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt; 24 a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt; 25 } 26 void init(){ 27 memset(first,-1,sizeof(first)); 28 memset(a,0,sizeof(a));cnt=-1;ans=0;flow=0; 29 } 30 int spfa(int s,int t){ 31 int q[10010],head=0,tail=1,maxn=10000,i,u,v,w; 32 memset(pre,-1,sizeof(pre)); 33 for(i=s;i<=t;i++) dis[i]=inf; 34 q[0]=s;dis[s]=0; 35 while(head!=tail){ 36 u=q[head];head=(head+1)%maxn; 37 // cout<<"spfa "<<u<<endl; 38 for(i=first[u];~i;i=a[i].next){ 39 v=a[i].to;w=a[i].w; 40 // cout<<" to "<<v<<ends<<dis[v]<<ends<<w+dis[u]<<endl; 41 if(a[i].cap&&dis[v]>dis[u]+w){ 42 dis[v]=dis[u]+w; 43 pre[v]=u;path[v]=i; 44 q[tail]=v;tail=(tail+1)%maxn; 45 } 46 } 47 } 48 return ~pre[t]; 49 } 50 inline int _min(int l,int r){return (l<r)?l:r;} 51 int mcmf(int s,int t){ 52 int f,u; 53 while(spfa(s,t)){ 54 f=inf; 55 for(u=t;u!=s;u=pre[u]) f=_min(f,a[path[u]].cap); 56 flow+=f;ans+=dis[t]*f; 57 // cout<<"mcmf "<<flow<<ends<<ans<<endl; 58 for(u=t;u!=s;u=pre[u]){ 59 a[path[u]].cap-=f; 60 a[path[u]^1].cap+=f; 61 } 62 } 63 } 64 int main(){ 65 freopen("digit.in","r",stdin); 66 freopen("digit.out","w",stdout); 67 int i,j; 68 n=read();m=read(); 69 for(i=1;i<=m;i++){ 70 for(j=1;j<=i+n-1;j++) x[i][j]=read(),id[i][j]=++tot; 71 } 72 //T1 73 init(); 74 for(i=1;i<=n;i++) add(0,id[1][i],0,1); 75 for(i=1;i<=m;i++){ 76 for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,1); 77 } 78 for(i=1;i<m;i++){ 79 for(j=1;j<=i+n-1;j++){ 80 add(id[i][j]+tot,id[i+1][j],-x[i][j],1); 81 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1); 82 } 83 } 84 for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],1); 85 mcmf(0,(tot<<1)+1); 86 printf("%d\n",-ans); 87 //T2 88 init(); 89 for(i=1;i<=n;i++) add(0,id[1][i],0,1); 90 for(i=1;i<=m;i++){ 91 for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf); 92 } 93 for(i=1;i<m;i++){ 94 for(j=1;j<=i+n-1;j++){ 95 add(id[i][j]+tot,id[i+1][j],-x[i][j],1); 96 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1); 97 } 98 } 99 for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf); 100 mcmf(0,(tot<<1)+1); 101 printf("%d\n",-ans); 102 //T3 103 init(); 104 for(i=1;i<=n;i++) add(0,id[1][i],0,1); 105 for(i=1;i<=m;i++){ 106 for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf); 107 } 108 for(i=1;i<m;i++){ 109 for(j=1;j<=i+n-1;j++){ 110 add(id[i][j]+tot,id[i+1][j],-x[i][j],inf); 111 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],inf); 112 } 113 } 114 for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf); 115 mcmf(0,(tot<<1)+1); 116 printf("%d",-ans); 117 }