感动,终于过了(由此我发现了自己是有多么的菜……)
其实其他几个发题解大佬都已经把思路讲的很清楚了,我就不细讲了,主要是提醒大家一下
可能这一题的提交记录中也只有我交了这么多次,发了三篇讨论,连着改了一个星期吧……
大致的思路:
-
-
第一问要保证路径互不相交,也就是不能让一个点被经过多次
-
是不是感觉很熟悉!是不是!没错,就是拆点大法!用拆点来保证只经过这个点一次即可QQwQ
-
-
-
第二问仅不允许在路径上相交,就没必要拆点啦QQwQ
-
同样的,用流量为1来保证路径只经过一次
-
-
-
第三问一看……噢,这不相当于是没有限制么QQQQQwQ!
-
激动的我们将流量开大并什么也不想管
-
以下是我主要出问题的几个点(求不要嘲讽):
-
memset赋负数时只能赋-1,赋其他的数会变成奇怪的负数,所以在判断时要看他是否<0,否则就会出错……
-
这一题不要看范围只有20就不开大数组范围,一定要开大!!,不然就会出现奇怪的错误,因为数组是连续的,所以一旦爆数组就会修改到其他几个数组然后就挂了……(像我就T到飞起……)
之前我改代码是发现……题解中没有一篇Dinic递归的代码!
于是给大家一个并手动普度众生
1 #include<bits/stdc++.h> 2 using namespace std; 3 inline int read() 4 { 5 int f=1,w=0;char x=0; 6 while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();} 7 while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();} 8 return f*w; 9 } 10 int head[200020],cur[200020],num_edge=-1; 11 int a[1001][1001],b[1001][1001],cnt; 12 int n,m,s,t,ans; 13 struct Edge 14 { 15 int next,to,dis,cos; 16 }edge[200020]; 17 inline void add(int from,int to,int dis,int cos) 18 { 19 edge[++num_edge].next=head[from]; 20 edge[num_edge].to=to; 21 edge[num_edge].dis=dis; 22 edge[num_edge].cos=cos; 23 head[from]=num_edge; 24 } 25 inline void clear() 26 { 27 num_edge=-1; 28 memset(head,-1,sizeof(head)); 29 ans=0; 30 } 31 int d[200000],v[200000],flo[200000]; 32 inline bool bfs() 33 { 34 memset(d,-50,sizeof(d)); 35 memset(v,0,sizeof(v)); 36 memset(flo,0,sizeof(flo)); 37 queue<int> q; 38 q.push(s); 39 d[s]=0; 40 v[s]=1;flo[s]=1; 41 while(!q.empty()) 42 { 43 int x=q.front(); 44 q.pop(); 45 v[x]=0; 46 for(int i=head[x];i!=-1;i=edge[i].next) 47 { 48 int y=edge[i].to; 49 if(edge[i].dis>0&&d[y]<d[x]+edge[i].cos) 50 { 51 d[y]=d[x]+edge[i].cos; 52 flo[y]=flo[x]+1; 53 if(!v[y]) { q.push(y); v[y]=1; } 54 } 55 } 56 } 57 if(d[t]<0) return 0; 58 else return 1; 59 } 60 int dfs(int pos,int dis) 61 { 62 if(pos==t) return dis; 63 for(int i=cur[pos];i!=-1;i=edge[i].next) 64 if(flo[edge[i].to]==flo[pos]+1&&edge[i].dis!=0&&d[edge[i].to]==d[pos]+edge[i].cos) 65 { 66 int data=dfs(edge[i].to,min(dis,edge[i].dis)); 67 if(data>0) 68 { 69 edge[i].dis-=data; 70 edge[i^1].dis+=data; 71 ans+=edge[i].cos; 72 cur[pos]=i; 73 return data; 74 } 75 } 76 return 0; 77 } 78 void Dinic() 79 { 80 while(bfs()) 81 { 82 memcpy(cur,head,sizeof(head)); 83 while(dfs(s,0x3f3f3f3f)); 84 } 85 } 86 int main(){ 87 memset(head,-1,sizeof(head)); 88 m=read(); 89 n=read(); 90 for(int i=1;i<=n;i++) 91 for(int j=1;j<=m+i-1;j++) 92 a[i][j]=read(),b[i][j]=++cnt; 93 s=0; 94 t=cnt*2+3; 95 for(int i=1;i<=m;i++) 96 add(s,b[1][i],1,0),add(b[1][i],s,0,0); 97 for(int i=1;i<n;i++) 98 for(int j=1;j<=m+i-1;j++) 99 { 100 add(b[i][j],b[i][j]+cnt,1,a[i][j]); 101 add(b[i][j]+cnt,b[i][j],0,-a[i][j]); 102 add(b[i][j]+cnt,b[i+1][j],1,0); 103 add(b[i+1][j],b[i][j]+cnt,0,0); 104 add(b[i][j]+cnt,b[i+1][j+1],1,0); 105 add(b[i+1][j+1],b[i][j]+cnt,0,0); 106 } 107 for(int i=1;i<=m+n-1;i++) 108 { 109 add(b[n][i],b[n][i]+cnt,1,a[n][i]); 110 add(b[n][i]+cnt,b[n][i],0,-a[n][i]); 111 add(b[n][i]+cnt,t,1,0); 112 add(t,b[n][i]+cnt,0,0); 113 } 114 Dinic(); 115 printf("%d ",ans); 116 clear(); 117 for(int i=1;i<=m;i++) 118 add(s,b[1][i],1,0),add(b[1][i],s,0,0); 119 for(int i=1;i<n;i++) 120 for(int j=1;j<=m+i-1;j++) 121 { 122 add(b[i][j],b[i+1][j],1,a[i][j]); 123 add(b[i+1][j],b[i][j],0,-a[i][j]); 124 add(b[i][j],b[i+1][j+1],1,a[i][j]); 125 add(b[i+1][j+1],b[i][j],0,-a[i][j]); 126 } 127 for(int i=1;i<=m+n-1;i++) 128 { 129 add(b[n][i],t,0x3f3f3f3f,a[n][i]); 130 add(t,b[n][i],0,-a[n][i]); 131 } 132 Dinic(); 133 printf("%d ",ans); 134 clear(); 135 for(int i=1;i<=m;i++) 136 add(s,b[1][i],1,0),add(b[1][i],s,0,0); 137 for(int i=1;i<n;i++) 138 for(int j=1;j<=m+i-1;j++) 139 { 140 add(b[i][j],b[i+1][j],0x3f3f3f3f,a[i][j]); 141 add(b[i+1][j],b[i][j],0,-a[i][j]); 142 add(b[i][j],b[i+1][j+1],0x3f3f3f3f,a[i][j]); 143 add(b[i+1][j+1],b[i][j],0,-a[i][j]); 144 } 145 for(int i=1;i<=m+n-1;i++) 146 { 147 add(b[n][i],t,0x3f3f3f3f,a[n][i]); 148 add(t,b[n][i],0,-a[n][i]); 149 } 150 Dinic(); 151 printf("%d ",ans); 152 }