震惊,某MnZn竟在讨论区做出如此事情
  • 板块P4843 清理雪道
  • 楼主Pwtking
  • 当前回复12
  • 已保存回复12
  • 发布时间2023/6/11 15:53
  • 上次更新2023/10/23 13:22:07
查看原帖
震惊,某MnZn竟在讨论区做出如此事情
774862
Pwtking楼主2023/6/11 15:53

感谢点进来的dalao们,如果您能为我这个MnZn提供帮助或者回复一下我就更感谢了orz。


理论上费用流是可以跑出最大流的,但是为什么我这个死循环了??

后来发现如果去掉主函数中

if (F[i]>0) add(S,i,F[i],0);

这句则不会死循环,但是WA了

请问为什么??

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7fffffff
const ll maxn=1000010;
ll S,T;
ll n,m,s,t;
ll head[maxn],dis[maxn],vis[maxn];
ll inq[maxn];
struct edge {ll to,next,w,cost;}e[maxn];
ll cnte=1,cur[maxn];
ll Cost,ans;
ll ax[4]={0,0,1,-1},ay[4]={1,-1,0,0};
ll F[maxn];
inline void add(ll u,ll v,ll w,ll c) {
	e[++cnte].to=v,e[cnte].w=w,e[cnte].cost=c,e[cnte].next=head[u],head[u]=cnte;
	e[++cnte].to=u,e[cnte].w=0,e[cnte].cost=-c,e[cnte].next=head[v],head[v]=cnte;
}
inline bool spfa() {
	queue<ll> q;
	for (ll i=0;i<=T;++i) dis[i]=inf,cur[i]=head[i];
	q.push(S);
	dis[S]=0,inq[S]=1;
	while (!q.empty()) {
		ll u=q.front();
		q.pop();
		inq[u]=0;
		for (ll i=head[u];i;i=e[i].next) {
			ll v=e[i].to;
			if (e[i].w>0&&dis[v]>dis[u]+e[i].cost) {
				dis[v]=dis[u]+e[i].cost;
				if (!inq[v]) q.push(v),inq[v]=1;
			}
		}
	}
	if (dis[t]!=inf) return true;
	return false;
}
inline ll dfs(ll u,ll sum) {
	vis[u]=1;
	if (u==T) return sum;
	ll tmp=0,used=0;
	for (ll i=cur[u];i;i=e[i].next) {
		cur[u]=i;
		ll v=e[i].to;
		if (e[i].w>0&&dis[v]==dis[u]+e[i].cost&&(!vis[v]||v==T)&&(tmp=dfs(v,min(e[i].w,sum-used)))) {
			e[i].w-=tmp,e[i^1].w+=tmp;
			Cost+=e[i].cost*tmp;
			used+=tmp;
			if (used>=sum) break;
		}
	}
	vis[u]=0;
	return used;
}
inline void dinic() {
	ans=Cost=0;
	while (spfa()) {
        ans+=dfs(S,inf);
        memset(vis,0,sizeof(vis));
		while (vis[T]);{
			memset(vis,0,sizeof(vis));
			ans+=dfs(S,inf);
		}
		
	}
}
inline ll in() {
    char a=getchar();
	ll t=0,f=1;
	while(a<'0'||a>'9') {if (a=='-') f=-1;a=getchar();}
    while(a>='0'&&a<='9') {t=(t<<1)+(t<<3)+a-'0';a=getchar();}
    return t*f;
}
signed main() {
	n=in();
	s=0,t=n+1;
	S=t+1,T=t+2;
	for (ll i=1;i<=n;++i) {
		m=in();
		add(s,i,inf,0);
		add(i,t,inf,0);
		for (ll j=1;j<=m;++j) {
			ll v=in();
			add(i,v,inf-1,0);
			F[i]-=1,F[v]+=1;
		}
	}
	for (ll i=1;i<=n;++i) {
		if (F[i]>0) add(S,i,F[i],0);//如果把这句去掉则不会死循环而会WA
		if (F[i]<0) add(i,T,-F[i],0);
	}
	dinic();
	add(t,s,inf,0);
	dinic();
	printf("%lld",e[cnte].w);
	return 0;
}
2023/6/11 15:53
加载中...