关于 ISAP 终止条件
查看原帖
关于 ISAP 终止条件
765446
MichaelWong楼主2023/6/23 06:55

rt,本来写的终止条件是

while(dis[s]<n) { memcpy(cur,head,sizeof head); flow+=dfs(s,inf); },

但这显然不对,所以我就增加了一个变量 top,top, 表示 dissdis_s 的理论合法最大值,然后我试了很多。

top←day×ntop \gets day \times n 是不对的;

top←(day+1)×ntop \gets (day+1) \times n 是不对的;

top←(day+1)×n−1top \gets (day+1) \times n -1 也是不对的;

top←day×(n+1)top \gets day \times (n+1) 还是不对的;

最后我仔细想了想,如果最大深度应该就是天数,但是深度因为可以恰巧是 dayday 所以好像应该加一?(加了一样例才过)

top←day+1,top \gets day+1, 现在 TLE #7 #11.

我有觉得是不是当天数很多的时候事实上走不了这么长,所以我又 top←min⁡(day+1,300)top \gets \min (day+1,300) (300 是 m×rim \times r_i 最大值。)但现在还是 T 那两个点。

有 dalao 写的是 ISAP 吗?我是这里的问题吗?应该怎么改捏……

完整代码

#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pii std::pair<int,int>
#define fsp(x) std::fixed<<std::setprecision(x)
#define forE(u) for(int p=head[u],v=to[p];p;p=next[p],v=to[p])
const int N=35,M=3e4+5,inf=1064;
int n,m,k,s,t,top,h[N],r[N],S[N][N],tot=0;
struct network {
	int cnt=1,head[M],to[M<<1],next[M<<1],lim[M<<1];
	inline void add(int u,int v,int w) {
		to[++cnt]=v,lim[cnt]=w,next[cnt]=head[u],head[u]=cnt;
		to[++cnt]=u,lim[cnt]=0,next[cnt]=head[v],head[v]=cnt;
	}
	int dis[M],cur[M],gap[M];
	int dfs(int u,int res) {
		if(u==t) return res;
		int flow=0;
		for(int &p=cur[u];p&&res;p=next[p]) {
			int c=std::min(res,lim[p]),v=to[p];
			if(dis[v]==dis[u]-1&&c) { int fl=dfs(v,c); flow+=fl,res-=fl,lim[p^1]+=fl,lim[p]-=fl; }
			if(!res) return flow;
		}
		if(--gap[dis[u]]==0) dis[s]=n;
		return ++gap[++dis[u]],flow;
	}
	int maxflow() {
		int flow=0; std::queue<int> q;
		memset(dis,-1,sizeof dis);
		gap[dis[t]=0]=1,q.push(t);
		while(!q.empty()) {
			int u=q.front(); q.pop();
			forE(u) if(dis[v]==-1&&!lim[p]) ++gap[dis[v]=dis[u]+1],q.push(v);
		}
		while(dis[s]<top) { memcpy(cur,head,sizeof head); flow+=dfs(s,inf); }
		return flow;
	}
} f;
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr); std::cout.tie(nullptr);
	std::cin>>n>>m>>k; s=1,t=0;
	for(int i=1;i<=m;++i) {
		std::cin>>h[i]>>r[i];
		for(int j=0;j<r[i];++j) std::cin>>S[i][j];
	}
	for(int day=1;day<=1000;++day) {
		int base=day*n+1; top=std::min(day+1,300);
		for(int i=1;i<=n;++i) f.add(base-n+i,base+i,inf);
		for(int i=1;i<=m;++i) {
			int pre=S[i][(day-1)%r[i]],cur=S[i][day%r[i]];
			pre+=pre>0?base-n:1,cur+=cur>0?base:1;
			f.add(pre,cur,h[i]);
		}
		if((tot+=f.maxflow())>=k) return std::cout<<day<<'\n' && 0;
	}
	std::cout<<"0\n";
	return 0;
}
2023/6/23 06:55
加载中...