两道比较基础的网络流题目,重点就是建图。
1458:题意就是给你一些东西它们的数据,其中一些是发电站,还有一些是用户的家里,其中还有一些是中转站。让你求最大的输送电量。
就是一道很基础的最大流题目,建超级源和汇,分别向发电站连边,从用户那连进边。
具体的读入只需要写一下读优即可去括号。、
CODE
#include<cstdio> #include<cstring> using namespace std; const int N=105,INF=1e9; struct edge { int to,next,c; }e[N*N*10]; int head[N],dep[N],q[N*10],n,np,nc,m,k,i,x,y,z,s,t; inline void read(int &x) { x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); } inline void write(int x) { if (x/10) write(x/10); putchar(x%10+'0'); } inline void add(int x,int y,int z) { e[++k].to=y; e[k].c=z; e[k].next=head[x]; head[x]=k; } inline int min(int a,int b) { return a<b?a:b; } inline int BFS() { memset(dep,0,sizeof(dep)); int H=0,T=1; q[1]=s; dep[s]=1; while (H<T) { int now=q[++H]; for (int i=head[now];i!=-1;i=e[i].next) if (!dep[e[i].to]&&e[i].c>0) { dep[e[i].to]=dep[now]+1; q[++T]=e[i].to; } } return dep[t]; } inline int DFS(int now,int dist) { if (now==t) return dist; int res=0; for (int i=head[now];i!=-1&&dist;i=e[i].next) if (dep[e[i].to]==dep[now]+1&&e[i].c>0) { int dis=DFS(e[i].to,min(dist,e[i].c)); dist-=dis; res+=dis; e[i].c-=dis; e[i^1].c+=dis; } if (!res) dep[now]=0; return res; } inline int Dinic() { int sum=0; while (BFS()) sum+=DFS(s,INF); return sum; } int main() { while (scanf("%d",&n)!=EOF) { memset(e,-1,sizeof(head)); memset(head,-1,sizeof(head)); read(np); read(nc); read(m); s=0; t=n+2; k=-1; for (i=1;i<=m;++i) { read(x); read(y); read(z); add(x+1,y+1,z); add(y+1,x+1,0); } for (i=1;i<=np;++i) { read(x); read(z); add(s,x+1,z); add(x+1,s,0); } for (i=1;i<=nc;++i) { read(x); read(z); add(x+1,t,z); add(t,s+1,0); } write(Dinic()); putchar(' '); } return 0; }
3456:题意比较难理解,而且还要输出方案。
大概是有n个工厂加工一种产品,其中每个产品都有p个部分。
其中1表示必须要这个部件,0表示必须不要,2表示可有可无。
然后给出所有工厂的单位时间内最多加工量和对输入输出的要求,让你求单位时间内最多加工多少个完整的产品(即所有部件都是1,刚开始所有的都是0)。
思路:拆点,对于所有的工厂拆成两个点分别连入度和出度。对于所有工厂间若可以连成流水线就连一条INF的边。
同时,由超级源向所有没有1的工厂连INF的边,所有没有1,2的工厂向超级汇连边。
注意必须用scanf(雾),用read超时(滑稽)
写了两个版本
EK CODE
#include<cstdio> #include<cstring> using namespace std; const int N=55<<1,P=15<<1,INF=1e9; int f[N],pre[N],q[N],c[N][N],a[N][P],n,p,x,s,t,m; inline void write(int x) { if (x/10) write(x/10); putchar(x%10+'0'); } inline int min(int a,int b) { return a<b?a:b; } inline int BFS(void) { memset(pre,-1,sizeof(pre)); memset(f,0,sizeof(f)); f[s]=INF; q[1]=s; int head=0,tail=1; while (head<tail) { int now=q[++head]; for (register int i=s;i<=t;++i) if (pre[i]==-1&&c[now][i]) { pre[i]=now; f[i]=min(f[now],c[now][i]); q[++tail]=i; } } return f[t]; } inline int max_flow(void) { int sum=0,inc; while (inc=BFS()) { int now=t; while (now!=s) { c[pre[now]][now]-=inc; c[now][pre[now]]+=inc; now=pre[now]; } sum+=inc; } return sum; } int main() { register int i,j,k; while (scanf("%d%d",&p,&n)!=EOF) { memset(c,0,sizeof(c)); s=0; t=2*n+1; m=0; for (i=1;i<=n;++i) { scanf("%d",&x); c[i][i+n]=x; bool flag_0=1,flag_1=1; for (j=1;j<=p;++j) { scanf("%d",&a[i][j]); if (a[i][j]==1) flag_0=0; } for (j=1;j<=p;++j) { scanf("%d",&a[i][j+p]); if (a[i][j+p]!=1) flag_1=0; } if (flag_0) c[s][i]=INF; if (flag_1) c[i+n][t]=INF; } for (i=1;i<=n;++i) for (j=1;j<=n;++j) { bool flag=1; for (k=1;k<=p;++k) if (a[i][k+p]+a[j][k]==1) { flag=0; break; } if (flag) c[i+n][j]=INF; } write(max_flow()); putchar(' '); for (i=n+1;i<=2*n;++i) for (j=1;j<=n;++j) if (c[j][i]&&i-n!=j) ++m; write(m); putchar(' '); for (i=n+1;i<=2*n;++i) for (j=1;j<=n;++j) if (c[j][i]&&i-n!=j) write(i-n),putchar(' '),write(j),putchar(' '),write(c[j][i]),putchar(' '); } return 0; }
Dinic CODE
#include<cstdio> #include<cstring> using namespace std; const int N=55<<1,P=15<<1,INF=1e9; struct data { int to,next,c; }e[N*N]; int head[N],dep[N],q[N],a[N][P],n,p,x,s,t,m,tot; inline void write(int x) { if (x/10) write(x/10); putchar(x%10+'0'); } inline void add(int x,int y,int z) { e[++tot].to=y; e[tot].c=z; e[tot].next=head[x]; head[x]=tot; } inline int min(int a,int b) { return a<b?a:b; } inline bool BFS(void) { memset(dep,0,sizeof(dep)); q[1]=s; dep[s]=1; int H=0,T=1; while (H<T) { int now=q[++H]; for (register int i=head[now];i!=-1;i=e[i].next) if (!dep[e[i].to]&&e[i].c) { dep[e[i].to]=dep[now]+1; q[++T]=e[i].to; } } return dep[t]; } inline int DFS(int now,int dist) { if (now==t) return dist; int res=0; for (register int i=head[now];i!=-1&&dist;i=e[i].next) if (dep[e[i].to]==dep[now]+1&&e[i].c) { int dis=DFS(e[i].to,min(e[i].c,dist)); dist-=dis; res+=dis; e[i].c-=dis; e[i^1].c+=dis; } if (!res) dep[now]=0; return res; } inline int Dinic(void) { int sum=0; while (BFS()) sum+=DFS(s,INF); return sum; } inline int abs(int x) { return x>0?x:-x; } int main() { register int i,j,k; while (scanf("%d%d",&p,&n)!=EOF) { memset(e,-1,sizeof(e)); memset(head,-1,sizeof(head)); s=0; t=2*n+1; m=0; tot=-1; for (i=1;i<=n;++i) { scanf("%d",&x); add(i,i+n,x); add(i+n,i,0); bool flag_0=1,flag_1=1; for (j=1;j<=p;++j) { scanf("%d",&a[i][j]); if (a[i][j]==1) flag_0=0; } for (j=1;j<=p;++j) { scanf("%d",&a[i][j+p]); if (a[i][j+p]!=1) flag_1=0; } if (flag_0) add(s,i,INF),add(i,s,0); if (flag_1) add(i+n,t,INF),add(t,i+n,0); } for (i=1;i<=n;++i) for (j=1;j<=n;++j) { bool flag=1; for (k=1;k<=p;++k) if (a[i][k+p]+a[j][k]==1) { flag=0; break; } if (flag) add(i+n,j,INF),add(j,i+n,0); } write(Dinic()); putchar(' '); for (i=1;i<=tot;i+=2) if (e[i].c&&abs(e[i].to-e[i-1].to)!=n&&e[i].to!=s&&e[i-1].to!=t) ++m; write(m); putchar(' '); for (i=1;i<=tot;i+=2) if (e[i].c&&abs(e[i].to-e[i-1].to)!=n&&e[i].to!=s&&e[i-1].to!=t) write(e[i].to-n),putchar(' '),write(e[i-1].to),putchar(' '),write(e[i].c),putchar(' '); } return 0; }