BZOJ 2929 洞穴攀行

来源:互联网 发布:重装系统备份软件 编辑:程序博客网 时间:2024/04/28 23:35

题目大意:

中文题。


解题思路:

裸网络流。


感觉dinic用的顺手了


#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<queue>#define LL long long#define db double#define maxn 10000000#define EPS 1e-15#define inf 1000000000using namespace std;int n,cnt=1,ans;int h[205],q[205],last[205],cur[205];struct edge{int to,next,w;}e[40005];void insert(int u,int v,int w){e[++cnt].to=v; e[cnt].w=w; e[cnt].next=last[u]; last[u]=cnt;e[++cnt].to=u; e[cnt].w=0; e[cnt].next=last[v]; last[v]=cnt;}bool bfs(){int head=0,tail=1;memset(h,-1,sizeof(h));h[1]=0; q[0]=1;while (head!=tail) {int now=q[head]; head++;for (int i=last[now];i;i=e[i].next)if (e[i].w && h[e[i].to]==-1){h[e[i].to]=h[now]+1;q[tail++]=e[i].to;}}return h[n]!=-1;}int dfs(int x,int f){if (x==n) return f;int w,used=0;for (int i=cur[x];i;i=e[i].next)if (h[e[i].to]==h[x]+1){w=f-used;w=dfs(e[i].to,min(w,e[i].w));e[i].w-=w; e[i^1].w+=w;used+=w;if (used==f) return f;}if (!used) h[x]=-1;return used;}int dinic(){while (bfs()){for (int i=1;i<=n;i++) cur[i]=last[i];ans+=dfs(1,inf);}return ans;}int main(){scanf("%d",&n);int x;for (int i=1;i<n;i++){scanf("%d",&x);while (x--){int v;scanf("%d",&v);if (i==1 || v==n) insert(i,v,1);else insert(i,v,inf);}}printf("%d\n",dinic());return 0;}


0 0