建图差不多和以前做的差不多,就是最后询问这个闭合子图有多少个的时候,只要输出这个图的S集合,就是进行dfs能遍历到的点一定在S集合中,不能遍历到的点在T集合中
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn=;
const long long INF=1LL<<;
typedef long long LL;
struct Dinic
{ struct Edge{
LL from,to,cap,flow;
Edge(LL cfrom=,LL cto=,LL ccap=,LL cflow=)
{
from=cfrom; to=cto; cap=ccap; flow=cflow;
}
};
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
void init(int n)
{
m=;
this->n=n;
for(int i=; i<=n; i++)G[i].clear();
edges.clear();
}
void addEdge(LL from,LL to, LL cap)
{
edges.push_back(Edge(from,to,cap,) );
edges.push_back(Edge(to,from,,));
m+=;
G[from].push_back(m-);
G[to].push_back(m-);
}
bool BFS()
{
memset(vis,,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s]=;
vis[s]=;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=; i<G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(vis[e.to]==false&&e.cap>e.flow)
{
vis[e.to]=;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
}
LL DFS(int x,LL a)
{
if(x==t||a==)return a;
LL flow=,f;
for(int &i=cur[x]; i<G[x].size(); i++)
{
Edge &e=edges[G[x][i]];
LL dd =min(a,e.cap-e.flow);
if(d[x]+==d[e.to]&&(f=DFS(e.to,dd))>)
{
e.flow+=f;
edges[G[x][i]^].flow-=f;
flow+=f;
a-=f;
if(a==)break;
}
}
return flow;
}
LL Maxflow(int s,int t)
{
this->s=s;this->t=t;
LL flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow+=DFS(s,INF);
}
return flow;
}
void find(int cur)
{
vis[cur]=true;
for(int i=; i<G[cur].size(); i++)
{
Edge &e=edges[G[cur][i]];
if(vis[e.to]||e.cap<=e.flow)continue;
find(e.to);
}
}
int solve()
{
memset(vis,,sizeof(vis));
for(int i=; i<G[s].size(); i++)
{
Edge &e=edges[G[s][i]];
if(vis[e.to]||e.cap<=e.flow)continue;
find(e.to);
}
int ans=;
for(int i=; i<=n-; i++)
ans+=vis[i];
return ans;
}
}T;
int P[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==)
{
LL S1=,S2=;
T.init(n+);
for(int i=; i<=n; i++)
{
scanf("%d",&P[i]);
if(P[i]>){
S1+=P[i];S2+=P[i];
T.addEdge(n+,i,P[i]);
}else{
S1+=-P[i];
T.addEdge(i,n+,-P[i]);
}
}
for(int i=; i<=m; i++)
{
int a,b;
scanf("%d%d",&a,&b);
T.addEdge(a,b,S1);
}
LL a1=T.Maxflow(n+,n+);
LL a2=T.solve();
printf("%I64d %I64d\n",a2,S2-a1);
}
return ;
}