过了but有一个疑问
查看原帖
过了but有一个疑问
701408
lao_wang楼主2024/6/8 11:13

这两个代码是等价的吗?

用另一种建图写的

#include<bits/stdc++.h>
#define int long long
#define inf 2147483647
#define N 112345
using namespace std;
int n , s , t , ss , tt , head[N] , temp_head[N] , now[N] , dep[N] , yan=0 , cnt=0 , in[N] ;
bool f[N] ;
struct node{
	int to , next , w ;
}e[N<<2],temp[N<<2];
void use(int u,int v,int w){
	e[cnt].to = v ;
	e[cnt].w = w ;
	e[cnt].next = head[u] ;
	head[u] = cnt++ ;
}
void newnet(int u,int v,int w){
	use(u,v,w) ;
	use(v,u,0) ;
}
bool bfs(){
	for(int i=1;i<=n+4;i++) now[i] = head[i] , f[i] = 0 , dep[i] = inf ;
	queue<int> q ;
	q.push(s) ;
	dep[s] = 0 ;
	while(!q.empty()){
		int u=q.front() ;
		q.pop() ;
		f[u] = 0 ;
		for(int i=head[u];~i;i=e[i].next){
			int x=e[i].to ;
			if(dep[u]+1<dep[x]&&e[i].w){
				dep[x] = dep[u]+1 ;
				if(!f[x]){
					f[x] = 0 ;
					q.push(x) ;
				}
			}
		}
	}
	return dep[t]!=inf ;
}
int dfs(int u,int sum){
	if(u==t) return sum ;
	int use=0 ;
	for(int i=now[u];~i;i=e[i].next){
		now[u] = i ;
		int x=e[i].to ;
		if(!e[i].w||dep[u]+1!=dep[x]) continue ;
		int temp=dfs(x,min(sum,e[i].w)) ;
		if(!temp) continue ;
		e[i].w -= temp ;
		e[i^1].w += temp ;
		use += temp ;
		sum -= temp ;
		if(!sum) break ;
	}
	return use ;
}
int dinic(){
	int ans=0 ;
	while(bfs()) ans += dfs(s,inf) ;
	return ans ;
}
signed main(){
	memset(head,-1,sizeof head) ;
	cin >> n ;
	s = n+1 ; t = s+1 ; ss = t+1 ; tt = ss+1 ;
	for(int i=1;i<=n;i++){
		newnet(s,i,inf) ;
		newnet(i,t,inf) ;
		int m ;
		scanf("%lld",&m) ;
		for(int j=1;j<=m;j++){
			int u ;
			scanf("%lld",&u) ;
			newnet(i,tt,1) ;
			newnet(ss,u,1) ;
			newnet(i,u,inf-1) ;
			yan++ ;
		}
	}
	for(int i=1;i<=n+4;i++) temp_head[i] = head[i] ;
	for(int i=0;i<cnt;i++) temp[i] = e[i]  ;
	int l=1 , r=12333 ;
	while(l<=r){
		int mid=(r+l)>>1 ;
		newnet(t,s,mid) ;
		swap(ss,s) ;
		swap(tt,t) ;
		int c=dinic() ;
		if(c==yan) r = mid-1 ;
		else l = mid+1 ;
		swap(ss,s) ;
		swap(tt,t) ;
		cnt -= 2 ;
		for(int i=1;i<=n+4;i++) head[i] = temp_head[i] ;
		for(int i=0;i<cnt;i++) e[i] = temp[i] ;
	}
	cout << r+1 ;
	return 0;
}

题解思路写的

#include<bits/stdc++.h>
#define int long long
#define inf 2147483647
#define N 112345
using namespace std;
int n , s , t , ss , tt , head[N] , temp_head[N] , now[N] , dep[N] , yan=0 , cnt=0 , in[N] ;
bool f[N] ;
struct node{
	int to , next , w ;
}e[N<<2],temp[N<<2];
void use(int u,int v,int w){
	e[cnt].to = v ;
	e[cnt].w = w ;
	e[cnt].next = head[u] ;
	head[u] = cnt++ ;
}
void newnet(int u,int v,int w){
	use(u,v,w) ;
	use(v,u,0) ;
}
bool bfs(){
	for(int i=1;i<=n+5;i++) now[i] = head[i] , f[i] = 0 , dep[i] = inf ;
	queue<int> q ;
	q.push(s) ;
	dep[s] = 0 ;
	while(!q.empty()){
		int u=q.front() ;
		q.pop() ;
		f[u] = 0 ;
		for(int i=head[u];~i;i=e[i].next){
			int x=e[i].to ;
			if(dep[u]+1<dep[x]&&e[i].w){
				dep[x] = dep[u]+1 ;
				if(!f[x]){
					f[x] = 0 ;
					q.push(x) ;
				}
			}
		}
	}
	return dep[t]!=inf ;
}
int dfs(int u,int sum){
	if(u==t) return sum ;
	int use=0 ;
	for(int i=now[u];~i;i=e[i].next){
		now[u] = i ;
		int x=e[i].to ;
		if(!e[i].w||dep[u]+1!=dep[x]) continue ;
		int temp=dfs(x,min(sum,e[i].w)) ;
		if(!temp) continue ;
		e[i].w -= temp ;
		e[i^1].w += temp ;
		use += temp ;
		sum -= temp ;
		if(!sum) break ;
	}
	return use ;
}
int dinic(){
	int ans=0 ;
	while(bfs()) ans += dfs(s,inf) ;
	return ans ;
}
signed main(){
	memset(head,-1,sizeof head) ;
	cin >> n ;
	s = n+1 ; t = s+1 ; ss = t+1 ; tt = ss+1 ;
	for(int i=1;i<=n;i++){
		newnet(s,i,inf) ;
		newnet(i,t,inf) ;
		int m ;
		scanf("%lld",&m) ;
		for(int j=1;j<=m;j++){
			int u ;
			scanf("%lld",&u) ;
			newnet(i,u,inf-1) ;
			in[i]-- , in[u]++ ;
		}
	}
	for(int i=1;i<=n+4;i++) if(in[i]>0) yan += in[i] , newnet(ss,i,in[i]) ; else newnet(i,tt,-in[i]) ;
	for(int i=1;i<=n+4;i++) temp_head[i] = head[i] ;
	for(int i=0;i<cnt;i++) temp[i] = e[i]  ;
	int l=1 , r=12321 ;
	while(l<=r){
		int mid=(l+r)>>1 ;
		newnet(t,s,mid) ;
		swap(ss,s) ;
		swap(tt,t) ;
		int c=dinic() ;
		if(c==yan) r = mid-1 ;
		else l = mid+1 ;
		swap(ss,s) ;
		swap(tt,t) ;
		cnt -= 2 ;
		for(int i=1;i<=n+4;i++) head[i] = temp_head[i] ;
		for(int i=0;i<cnt;i++) e[i] = temp[i] ;
	}
	cout << r+1 ;
	return 0;
}
2024/6/8 11:13
加载中...