TLE#1,#2MnZn求助
查看原帖
TLE#1,#2MnZn求助
774330
justalearner楼主2023/7/11 22:06

用了Dinic>_<。前两个点跑了1.2s

#include<cstdio>
#include<cstring>
#define ll long long
const int INF=(1ll<<31)-1;
const int E=5e4+10,V=4e3+10;
struct networkflow
{
	int nx[E],ls[V],to[E],cap[E],cst[E],tot=1;
	void addedge(int u,int v,int capacity,int cost)
	{
		nx[++tot]=ls[u];
		to[ls[u]=tot]=v;
		cap[tot]=capacity;
		cst[tot]=cost;
	}
	void add(int u,int v,int capacity,int cost)
	{
		addedge(u,v,capacity,cost);
		addedge(v,u,0,-cost);
	}
	int dis[V],q[V],cur[V];
	bool vis[V];
	bool SPFA(int s,int t)
	{
		memset(dis,0x3f,sizeof dis);
		memcpy(cur,ls,sizeof cur);
		int head=0,tail=1;
		dis[q[1]=s]=0;
		while(head<tail)
		{
			int u=q[++head];vis[u]=0;
//			printf("bfs %d\n",u);
			for(int i=ls[u];i;i=nx[i])
			if(cap[i]&&dis[to[i]]>dis[u]+cst[i])
			{
				dis[to[i]]=dis[u]+cst[i];
				if(!vis[to[i]])
				vis[q[++tail]=to[i]]=1;
			}
		}
		return dis[t]!=dis[0];
	}
	ll min(ll a,ll b) {return a<b?a:b;}
	ll mincost;
	ll dfs(int u,int t,ll flow=INF)
	{
//		printf("dfs %d\n",u);
		if(u==t) return flow;
		ll ret=0;vis[u]=1;
		for(int &i=cur[u];i&&flow;i=nx[i])
		if(!vis[to[i]]&&cap[i]&&dis[to[i]]==dis[u]+cst[i])
		{
			ll f=dfs(to[i],t,min(flow,cap[i]));
			ret+=f;flow-=f;cap[i]-=f;cap[i^1]+=f;
			mincost+=f*cst[i];
		}
		vis[u]=0;
		return ret;
	}
	ll dinic(int s,int t)
	{
		ll ret=0;
		while(SPFA(s,t))
		ret+=dfs(s,t);
		return ret;
	}
}F,tmp;
int m;
int f1(int x,int y) {return (2*m-2+x)*(x-1)+2*y-1;}
int f2(int x,int y) {return f1(x,y)+1;}
const int N=1e3;
int a[N][N];
int main()
{
	int n;scanf("%d%d",&m,&n);
	int s=f2(n,n+m-1)+1,t=s+1;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=i+m-1;j++)
	{
		scanf("%d",&a[i][j]);
		if(i==1) F.add(s,f1(i,j),1,0);else{
		if(j<i+m-1) F.add(f2(i-1,j),f1(i,j),1,0);
		if(j>1) F.add(f2(i-1,j-1),f1(i,j),1,0);}
		F.add(f1(i,j),f2(i,j),1,-a[i][j]);
		if(i==n) F.add(f2(i,j),t,1,0);
	}
	tmp=F;F.dinic(s,t);
	printf("%d\n",-F.mincost);
	F=tmp;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=i+m-1;j++)
	{
		F.add(f1(i,j),f2(i,j),INF,-a[i][j]);
		if(i==n) F.add(f2(i,j),t,INF,0);
	}
	tmp=F;F.dinic(s,t);
	printf("%d\n",-F.mincost);
	F=tmp;
	for(int i=2;i<=n;i++)
	for(int j=1;j<=i+m-1;j++)
	{
		if(j<i+m-1) F.add(f2(i-1,j),f1(i,j),INF,0);
		if(j>1) F.add(f2(i-1,j-1),f1(i,j),INF,0);
	}
	F.dinic(s,t);
	printf("%d\n",-F.mincost);
}
2023/7/11 22:06
加载中...