嗯,我又來造福羣衆了.
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int n,m,inf=123456789; //int a[3010][3010],check,v[3010],forward,ans; int check,v[3010],forward,ans; struct edge { int y,v,next; }e[50010]; int tot,head[2010]; /* void dfs(int x,int l=inf) { //cout<<x<<endl; v[x]=1; if(x==n) { check=1; forward=l; ans+=l; return ; } for(int i=1;i<=2*n;i++) { if(a[x][i]>0&&!v[i]) { dfs(i,min(l,a[x][i])); if(check) { a[x][i]-=forward; a[i][x]+=forward; return ; } } } }*/ void add(int x,int y,int v=inf) { tot++; e[tot]=(edge){y,v,head[x]}; head[x]=tot; } void dfs(int x,int l=inf) { v[x]=1; if(x==n){ check=1; forward=l; ans+=l; return ; } for(int i=head[x];i;i=e[i].next) { if(e[i].v>0&&!v[e[i].y]) { dfs(e[i].y,min(l,e[i].v)); if(check) { e[i].v-=forward; e[i^1].v+=forward; return ; } } } } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();m=read();tot=1; for(register int i=2;i<n;i++) { add(i,i+n,1); add(i+n,i,1); /*a[i][i+n]=1; a[i+n][i]=1;*/ } for(;m;m--) { int tx=read(); int ty=read(); if(tx>ty) swap(tx,ty); if(tx==1) { //a[1][ty]=inf; add(1,ty); add(ty,1,0); } else if(ty==n) { //a[tx+n][n]=inf; //a[n][tx]=0; add(tx+n,n); add(n,tx+n,0); } else { /*a[tx+n][ty]=inf; a[ty+n][tx]=inf;*/ add(tx+n,ty); add(ty,tx+n,0); add(ty+n,tx); add(tx,ty+n,0); } } /*for(int i=1;i<=2*n;i++) for(int f=1;f<=2*n;f++) if(a[i][f]) cout<<i<<' '<<f<<' '<<a[i][f]<<endl;*/ /*for(int i=2;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(1); } cout<<(ans==0?ans:ans-1);/*//cout<<' '<<clock();*/ }
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<deque> #include<set> using namespace std; int ans[60][60][60][60],o[60][60]; int n,m; int i,f; int xi,yi,xf,yf; inline int maxx(int a,int b,int c,int d) { return max(max(a,b),max(c,d)); } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("123.in","r",stdin); cin>>n>>m; for(i=1;i<=n;i++) for(f=1;f<=m;f++) cin>>o[i][f]; for(xi=2;xi<=n;xi++) for(yi=1;yi<m;yi++) for(xf=1;xf<xi;xf++) for(yf=2;yf<=m;yf++) ans[xi][yi][xf][yf]=maxx(ans[xi-1][yi][xf-1][yf],ans[xi-1][yi][xf][yf-1],ans[xi][yi-1][xf-1][yf],ans[xi][yi-1][xf][yf-1])+o[xi][yi]+o[xf][yf]; cout<<ans[n][m-1][n-1][m]; }
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int inf=123456789,forward,check,ans,v[110]; int n,m,head[110],tot,can[1010],sum[1010]; //int e[10][10]; struct edge { int y,v,next; }e[100010]; void add(int x,int y,int v) { tot++; e[tot]=(edge){y,v,head[x]}; head[x]=tot; //e[x][y]=v; } void dfs(int x,int l=10*inf) { v[x]=1; if(x==n+1) { check=1; ans+=l; forward=l; return ; } for(register int i=head[x];i;i=e[i].next) { if(e[i].v>0&&!v[e[i].y]) { dfs(e[i].y,min(l,e[i].v)); if(check) { e[i].v-=forward; e[i^1].v+=forward; return ; } } } /* for(register int i=0;i<=n+1;i++) { if(a[x][i]>0&&!v[i]) { dfs(*/ } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); tot=1; m=read(); n=read(); for(register int i=1;i<=m;i++) sum[i]=read(); for(register int i=1;i<=n;i++) { for(register int A=read();A;A--) { int a=read(); if(can[a]) { add(can[a],i,inf); add(i,can[a],0); } else { add(0,i,sum[a]); add(i,0,0); } can[a]=i; } add(i,n+1,read()); add(n+1,i,0); } /*for(register int i=2;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(0); } cout<<ans; /*for(register int i=2;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ }
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } const int oo=1000000; int n,m,d,F,a[410][410],sum=0,forward; bool vis[410],check=1; void dfs(int k,int l=oo) { vis[k]=1; if(k==2*n+d+F+1) { check=1; sum+=l; forward=l; return; } for(int i=0;i<=2*n+d+F+1;i++) { if((a[k][i]>0)&&(!vis[i])) { dfs(i,min(a[k][i],l)); if (check) { a[k][i]-=forward; a[i][k]+=forward; return; } } } } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();F=read();d=read(); for(int i=1;i<=n;i++) { int f=read(),j=read(); for(;f;f--) { a[read()+2*n][i]=1; } for(;j;j--) { a[i+n][read()+2*n+F]=1; } a[i][i+n]=1; } for(int i=1;i<=F;i++) { a[0][i+2*n]=1; } for(int i=1;i<=d;i++) { a[i+2*n+F][d+2*n+F+1]=1; } while(check) { check=0; memset(vis,0,sizeof(vis)); dfs(0); } /*for(int i=0;i<=2*n+d+F+1;i++) { for(int f=0;f<=2*n+d+F+1;f++) { if(a[i][f]) { cout<<i<<' '<<f<<' '<<a[i][f]<<endl; } } }*/ cout<<sum; }
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int inf=123456789; int n,m,c1,c2,a[210][210],b[210][210],v[210],check,forward,G,G0; void dfs(int x,int l=inf) { if(x==c2) { forward=l; check=1; G+=forward; return ; } v[x]=1; for(int i=1;i<=2*n;i++) { if(a[x][i]>0&&!v[i]) { dfs(i,min(l,a[x][i])); if(check) { a[x][i]-=forward; a[i][x]+=forward; return ; } } } } int main() { n=read();m=read();c1=read();c2=read(); if(c1>c2) swap(c1,c2); for(int i=1;i<=n;i++) if(i!=c1&&i!=c2) a[i][i+n]=1,a[i+n][i]=1; for(;m;m--) { int tx=read();int ty=read(); if(ty==c1) swap(tx,ty); if(tx==c2) swap(tx,ty); if(tx==c1) a[c1][ty]=inf; else if(ty==c2) a[tx+n][c2]=inf; else a[tx+n][ty]=1,a[ty+n][tx]=1; }//建圖 memcpy(b,a,sizeof(a));//存邊 check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(c1); } cout<<G<<endl;//跑出最小割 int sum=G0=G; for(int now=1;sum;now++)//枚舉當前要刪那個點 { if(now==c1||now==c2) continue; G=0; memcpy(a,b,sizeof(a)); for(int i=1;i<=2*n;i++) a[now][i]=a[i][now]=a[now+n][i]=a[i][now+n]=0; check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(c1); }//跑刪掉這個點後的最小割 if(G<G0)//如果小於的話就更新G0,刪邊 { G0=G; cout<<now<<' '; sum--; for(int i=1;i<=2*n;i++) b[now][i]=b[i][now]=b[now+n][i]=b[i][now+n]=0; } } //cout<<clock(); }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #define oo 0x7fffffff using namespace std; int head,tail,level[110],q[110],s,t,sum=0,rev[10010],len,lin[110]; int m,n,Id[10010],cnt,ans; struct node{ int y,v,ne; }edge[10010]; struct node1{ int v,id; }e[10010]; inline bool mycmp(node1 a,node1 b) {return a.v>b.v||a.v==b.v&&a.id<b.id;} inline bool mycmp1(int a,int b) {return a<b;} void addedge(int x,int y,int v) { edge[++len].y=y;edge[len].v=v;edge[len].ne=lin[x];lin[x]=len;rev[len]=len+1; edge[++len].y=x;edge[len].v=0;edge[len].ne=lin[y];lin[y]=len;rev[len]=len-1; } int read(){ int x=0,y=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-')y=-1;ch=getchar();} while (isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*y; } bool make_level(){ head=0,tail=1;q[1]=s;memset(level,-1,sizeof(level));level[s]=0; while (head++<tail){ int tn=q[head]; for (int i=lin[tn],y;i;i=edge[i].ne) if (edge[i].v&&level[y=edge[i].y]==-1){ level[y]=level[tn]+1; q[++tail]=y; } } return level[t]!=-1; } int max_flow(int k,int flow){ if (k==t) return flow; int maxflow=0,d; for (int i=lin[k];i&&maxflow<flow;i=edge[i].ne) if (edge[i].v&&level[edge[i].y]==level[k]+1) if (d=max_flow(edge[i].y,min(flow-maxflow,edge[i].v))){ edge[i].v-=d;edge[rev[i]].v+=d;maxflow+=d; } if (!maxflow)level[k]=-1; return maxflow; } void dinic(){ int d; while (make_level()) while (d=max_flow(s,oo)) sum+=d; } void init(){ n=read();m=read(); s=1,t=n; int x,y,v; for (int i=1;i<=m;i++){ x=read();y=read();v=read(); addedge(x,y,v); } } int main(){ init(); dinic(); printf("%d ",sum); ans=sum; for (int j=1;j<=len;j+=2){edge[j].v+=edge[rev[j]].v;edge[rev[j]].v=0;} for (int i=1;i<=m;i++){e[i].v=edge[i*2-1].v;e[i].id=i;} sort(e+1,e+1+m,mycmp); for (int i=1;i<=m&&ans;i++){ int id=e[i].id,v=e[i].v; sum=0; edge[id*2-1].v=0; dinic(); for (int j=1;j<=len;j+=2){edge[j].v+=edge[rev[j]].v;edge[rev[j]].v=0;} if (ans-sum==v){ ans=sum; Id[++cnt]=id; } else edge[id*2-1].v=v; } printf("%d\n",cnt); sort(Id+1,Id+1+cnt); for (int i=1;i<=cnt;i++) printf("%d\n",Id[i]); return 0; }
網絡流最難的是建圖.我就把建圖說一下好了.
p1320.
無向圖,求至少割幾個點使得1到n不連通.輸出答案減一.
把點拆成i和i+n,連雙向邊,流量都是1.
對於圖中的邊,如果是(1,y)這樣的形式就連1到y.如果是(x,n)這樣的形式就連x+n,n.否則對於(x,y),連(x+n,y)和(y+n,x).這些都是單向邊且流量爲inf.我們還需要建一個反向邊以供增廣.
然後從1往外跑最大流.輸出最大流>0?最大流-1:最大流.
p1670
水了個n^4dp,以後再填坑.
p1609
令0爲源點,1-n爲顧客,n+1爲匯點.
先把豬圈裏豬的數量存起來.
維護每個豬圈最後一次是被哪個顧客打開的.對於每個顧客能打開的豬圈,如果之前有顧客打開過就從上一個顧客連一條流量爲inf的邊,否則從源點向顧客連一條流量爲該豬圈裏豬的數量的邊.最後向匯點連一條流量爲需求的邊.更新"最後一次是被哪個顧客打開的".
p1324
把點拆成1-n和n+1到2*n,令0爲源點,2*n+1-2*n+F爲食品,2*n+F+1到2*n+F+d爲飲料,2*n+F+d+1爲匯點.先連邊i到i+n約束牛,匯點連食品,飲料們連源點. 對於牛i,食品連i,i+n連飲料.以上邊權都爲1.
p1342
p1320的加強版.拆點後跑最大流.記錄當前最大流爲G0.爲了輸出字典序最小字典序的方案,從小到大枚舉所有的點,假裝刪掉這個點,看最大流G是否小於G0.如果小於說明是可以刪掉它,更新G0,真的刪掉這個點.否則把那些邊還回去...
p1341
第一問是正經的最小割.