题意分析
最大权闭合和回路
代码总览
#include<cstdio>
#include<bitset>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int nmax = 60005;
const int INF = 0x3f3f3f3f;
typedef long long ll ;
typedef struct {
int to,nxt;
ll w;
}Edge;
Edge e[nmax<<1];
int head[nmax<<1],dep[nmax],cur[nmax];
int tot = 0,n,m,S,T;
bitset<nmax> visit;
ll ans = 0,w;
void add(int u, int v, ll w){
e[tot].to = v;
e[tot].nxt = head[u];
e[tot].w = w;
head[u] = tot ++;
}
bool bfs(){
memset(dep,-1,sizeof dep);
dep[S] = 0; queue<int> q; q.push(S);
while(!q.empty()){
int u = q.front(); q.pop();
for(int i = head[u]; i!= -1; i = e[i].nxt){
int v = e[i].to;
if(dep[v] == -1 && e[i].w){
dep[v] = dep[u] +1;
q.push(v);
}
}
}
return dep[T] != -1;
}
ll dfs(int now, ll flow){
if(now == T || flow == 0) return flow;
ll f = 0;
for(int & i = cur[now];i !=-1 ; i = e[i].nxt){
int v = e[i].to;
if(dep[v] == dep[now] + 1 && e[i].w){
ll temp = dfs(v, min(e[i].w,flow));
if(temp){
e[i].w -= temp;
e[i^1].w += temp;
f += temp;
flow -= temp;
if(flow == 0) break;
}
}
}
return f;
}
void dinic(){
while(bfs()){
for(int i = S;i<=T;++i) cur[i] = head[i];
while(ll tt = dfs(S,INF)) ans -= tt;
}
}
void findtag(int u){
if(u == T) return;
if(u != S) visit.set(u);
for(int i = head[u]; i!=-1; i = e[i].nxt)
if(e[i].w && !visit.test(e[i].to))
findtag(e[i].to);
}
int main(){
scanf("%d %d",&n,&m);
memset(head,-1,sizeof head);
int w; S = 0; T = n + 1; visit.reset();
for(int i = 1;i<=n;++i){
scanf("%lld",&w);
if(w > 0){
ans += w;
add(S,i,w);
add(i,S,0);
}
if(w < 0){
add(i,T,-w);
add(T,i,0);
}
}
int a,b;
for(int i = 1;i<=m;++i){
scanf("%d %d",&a,&b);
add(a,b,INF);
add(b,a,0);
}
dinic();
findtag(S);
printf("%d %lld\n",visit.count(),ans);
return 0;
}