标签:目的 set order 检查 方法 ios ext 思路 idt
●(做codevs1908时,发现测试数据也涵盖了1907,想要一并做了,但因为“技术”不佳,搞了一上午)
●09方格取数问题(codevs1907 方格取数3)
●13星际转移问题(codevs 1908)
●代码(为了AC掉codevs1908,把两份代码怼到一起了):
#include<iostream> #include<cstdio> #include<cstring> #define INF 0x3f3f3f3f using namespace std; int n,m,k,yue=1,ear=2,sz=4,ent=2,aim,tot,s,t; int sps[30][30],cw[30][2],ld[30],ls[30],head[30000],h[30000],q[30000]; int fa[30]; struct edge{ int to,cap,next; }e[300000]; bool special_read() { char s[100]; gets(s); int a[4]={0},o=1; int len=strlen(s); for(int i=0;i<len;i++) { if(‘0‘<=s[i]&&s[i]<=‘9‘) a[o]=a[o]*10+s[i]-‘0‘; else if(a[o]) o++; } n=a[1];m=a[2]; return k=a[3]; } int read(int &o) { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1;ch=getchar();} while(‘0‘<=ch&&ch<=‘9‘) {x=x*10+ch-‘0‘;ch=getchar();} o=x*f; } void add_edge(int u,int v,int cap) { e[ent]=(edge){v,cap,head[u]};head[u]=ent++; e[ent]=(edge){u,0,head[v]};head[v]=ent++; } void make_new_edge(int day) { for(int i=3;i<=n+3-1;i++) add_edge(ld[i],++sz,INF),ld[i]=sz; for(int i=1;i<=m;i++) { int t=day%cw[i][1],o=sps[i][t]; if(o==ear) add_edge(ear,++sz,cw[i][0]),ls[i]=sz; else if(o==yue) add_edge(ls[i],yue,cw[i][0]),ls[i]=0; else { if(ls[i])add_edge(ls[i],ld[o],cw[i][0]); ls[i]=ld[o]; } } } bool bfs(int s,int t) { memset(h,0,sizeof(h)); int l=0,r=1;q[1]=s;h[s]=1; while(l<r) { int u=q[++l]; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(h[v]||!e[i].cap) continue; h[v]=h[u]+1; q[++r]=v; } } return h[t]; } int dfs(int u,int res,int t) { if(u==t) return res; int flowout=0,f; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(!e[i].cap||h[v]!=h[u]+1) continue; f=dfs(v,min(res,e[i].cap),t); e[i].cap-=f; e[i^1].cap+=f; flowout+=f; res-=f; if(!res) break; } if(!flowout) h[u]=-1; return flowout; } int Dinic(int s,int t) { while(bfs(s,t)) { aim+=dfs(s,INF,t); } return aim; } void check_and_add(int a,int b,int c,int d) { c+=a; d+=b; if(c==0||c==n+1||d==0||d==m+1) return; int u=(a-1)*m+b,v=(c-1)*m+d; add_edge(u,v,INF); } int find(int x) { if(fa[x]!=x) return fa[x]=find(fa[x]); return x; } void unio(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) fa[fy]=fx; } void _1908() { for(int i=1;i<=25;i++) fa[i]=i; for(int i=1;i<=m;i++) { read(cw[i][0]);read(cw[i][1]); for(int j=0;j<cw[i][1];j++) { read(sps[i][j]); sps[i][j]+=2; if(j) for(int jj=0;jj<j;jj++) unio(sps[i][jj],sps[i][j]); } } if(find(yue)!=find(ear)) printf("0"); else { int day=0; add_edge(3,ear,k); add_edge(yue,4,INF); for(int i=3;i<=n+3-1;i++) ld[i]=++sz; for(int i=1;i<=m;i++) { int o=sps[i][0]; if(o==ear) add_edge(ear,++sz,cw[i][0]),ls[i]=sz; else if(o!=yue) ls[i]=ld[o]; } while(1) { ++day; make_new_edge(day); if(Dinic(3,4)==k) { printf("%d",day); break;} } } } void _1907() { int x,co=0; s=n*m+1;t=n*m+2; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { co=(i+j)%2; int u=(i-1)*m+j;scanf("%d",&x); tot+=x; if(!co) { add_edge(s,u,x); check_and_add(i,j,-1,0); check_and_add(i,j,1,0); check_and_add(i,j,0,-1); check_and_add(i,j,0,1); } else add_edge(u,t,x); } printf("%d",tot-Dinic(s,t)); } int main() { if(special_read()) _1908(); else _1907(); return 0; }
标签:目的 set order 检查 方法 ios ext 思路 idt
原文地址:http://www.cnblogs.com/zj75211/p/6659240.html