poj 1149

时间:2023-12-09 14:14:37

  

 #include <cstdio>
#include <cstring>
#include <queue>
#define _clr(x, y) memset(x, y, sizeof(x))
#define Min(x, y) (x < y ? x : y)
#define INF 0x3f3f3f3f
#define N 150
#define M 1005
using namespace std; int resi[N][N], h[N], ef[N];
int dist[N], pre[N];
int Maxf, S, T;
bool used[N];
queue<int> Q; // 一般预流推进算法 --47ms
void Push(int x)
{
for(int i=; i<=T; i++)
{
int tmp = Min(ef[x], resi[x][i]);
if(tmp> && (x==S || h[x]==h[i]+))
{
resi[x][i] -= tmp, resi[i][x] += tmp;
ef[x] -= tmp, ef[i] += tmp;
if(i==T) Maxf += tmp;
if(i!=S && i!=T) Q.push(i);
}
}
} void Push_Relabel(int n)
{
Maxf = ;
_clr(ef, );
_clr(h, );
h[S] = n, ef[S]=INF, ef[T]=-INF;
Q.push(S);
while(!Q.empty())
{
int x = Q.front();
Q.pop();
Push(x);
if(x!=S && x!=T && ef[x]>)
{
h[x]++;
Q.push(x);
}
}
printf("%d\n",Maxf);
} void Init(int m, int n)
{
int pig[M], last[M];
int num, k;
S=, T=n+;
_clr(last, );
_clr(resi, );
for(int i=; i<=m; i++)
scanf("%d", pig+i);
for(int i=; i<=n; i++)
{
scanf("%d", &num);
for(int j=; j<num; j++)
{
scanf("%d", &k);
if(last[k]==)
resi[S][i] += pig[k];
else
resi[last[k]][i] = INF;
last[k] = i;
}
scanf("%d", resi[i]+T);
}
} // 连续最短曾广路算法 --17ms
bool bfs_dinic()
{
_clr(dist, -);
dist[S] = ;
Q.push(S);
while(!Q.empty())
{
int u = Q.front();
Q.pop();
for(int i=; i<=T; i++)
{
if(dist[i]< && resi[u][i])
{
dist[i] = dist[u]+;
Q.push(i);
}
}
}
return dist[T]> ? : ;
} int dfs(int x, int f)
{
int a=;
if(x==T) return f;
for(int i=; i<=T; i++)
{
if(resi[x][i] && dist[i]==dist[x]+ && (a=dfs(i, Min(f, resi[x][i]))))
{
resi[x][i] -= a, resi[i][x] += a;
return a;
}
}
return ;
} void Dinic()
{
int ans=, a;
while(bfs_dinic())
while(a=dfs(, INF)) ans+= a;
printf("%d\n", ans);
} // EK算法 --0ms
bool bfs()
{
_clr(used, );
_clr(pre, -);
int Sta[N], top=;
used[S] = true;
Sta[top++] = S;
while(top)
{
int u = Sta[--top];
for(int i=; i<=T; i++)
{
if(resi[u][i] && !used[i])
{
used[i] = true;
pre[i] = u;
if(i==T) return true;
Sta[top++] = i;
}
}
}
return false;
}
void EK()
{
int maxf=, d;
while(bfs())
{
d = INF;
for(int i=T; i!=S; i=pre[i])
d = Min(d, resi[pre[i]][i]);
for(int i=T; i!=S; i=pre[i])
{
resi[pre[i]][i] -= d;
resi[i][pre[i]] += d;
}
maxf += d;
}
printf("%d\n", maxf);
}
int main()
{
int n, m;
while(~scanf("%d%d", &m, &n))
{
while(!Q.empty()) Q.pop();
Init(m, n);
EK();
//Push_Relabel(n);
//Dinic();
}
return ;
}