萌新求助 刚学网络流-998244353年,WA on #10 awa
查看原帖
萌新求助 刚学网络流-998244353年,WA on #10 awa
467585
banzong楼主2023/4/22 10:38
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#define maxn 5010
#define inf 1e9
using namespace std ;
int n , m ;
struct edge {
	int to , nxt , w ;
}e[maxn << 1] , E[maxn << 1];
int head[maxn] , cnt , Head[maxn] ,s , t , p[maxn] , deg[maxn] , res , d[maxn] , cut;
inline int id(int x , int y) {return x * 31 + y ;}
vector< int > pro[maxn] ;
bool vis[maxn] ;
void add_edge(int u , int v) { E[++cnt].to = v , E[cnt].nxt = Head[u] , Head[u] = cnt , deg[v] ++ ; pro[u].push_back(v) ;}
void add(int u , int v , int w) {
	e[++cnt].to = v , e[cnt].nxt = head[u] , e[cnt].w = w , head[u] = cnt ;
	e[++cnt].to = u , e[cnt].nxt = head[v] , e[cnt].w = 0 , head[v] = cnt ;
}
void topo( ) {
	queue< int > q ;
	for (int i = 1 ; i <= n ; i ++) for (int j = 1 ; j <= m ; j ++) if(!deg[id(i , j)]) q.push(id(i , j)) ;
	while(!q.empty()) {
		int x = q.front() ; q.pop() ;
		vis[x] = true ;
		for (int i = Head[x] ; i ; i = E[i].nxt) {
			int y = E[i].to ; deg[y] -- ;
			if(!deg[y] && !vis[y]) { vis[y] = true ; q.push(y) ; }
		}
	}
}
bool bfs( ) {
	for(int i = 0 ; i <= t ; i ++) d[i] = 0 ;
	queue< int > q ;
	d[s] = 1 ; q.push(s) ;
	while(!q.empty()) {
		int x = q.front() ; q.pop() ;
		for (int i = head[x] ; i ; i = e[i].nxt ) {
			int y = e[i].to ;
			if(d[y] || !e[i].w) continue ;
			d[y] = d[x] + 1 ; q.push(y) ;
			if(y == t) return true ;
		}
	}
	return false ; 
}
int dfs(int x , int flow) {
	int k , rest = flow ;
	if(x == t)	return flow ;
	for (int i = head[x] ; i ; i = e[i].nxt) {
		int y = e[i].to ;
		if(d[y] != d[x] + 1 || !e[i].w) continue ;
		k = dfs(y , min(rest , e[i].w)) ;
		rest -= k , e[i].w -= k , e[i ^ 1].w += k ;
		if(!k) d[y] = 0 ;
	}
	return flow - rest ;
}
void dinic( ) {
	int flow ;
	while (bfs( )) while(flow = dfs(s , inf)) cut += flow ;
}
int main ( ) {
	scanf("%d%d" , &n , &m) ;
	s = id(33 , 33) + 20 , t = s + 1 ;
	for (int i = 1 ; i <= n ; i ++) {
		for (int j = 1 ; j <= m ; j ++) {
			scanf("%d" , &p[id(i , j)]) ;
			if(j != m) add_edge(id(i , j + 1) , id(i , j)) ;
			int w ;
			scanf("%d" , &w) ;
			while (w--) {
				int x , y ;
				scanf("%d%d" , &x , &y) ;
				x ++ , y ++ ;
				add_edge(id(i , j) , id(x , y)) ;
			}
		}
	}
	topo( ) ; cnt = 1 ;
	for (int i = 1 ; i<= n ; i ++) {
		for (int j = 1 ; j <= m ; j ++) {
			int x = id(i , j) ;
			if(!vis[x]) continue ;
			for (auto y : pro[x]) if(vis[y]) add(y , x , inf) ;
			if(p[x] >= 0) { add(s , x , p[x]) ; res += p[x] ; }
			else	add(x , t , -p[x]) ;
		}
	}
	dinic( ) ;
	cout << res - cut << "\n" ;
	return 0 ;
}
2023/4/22 10:38
加载中...