萌新求助
查看原帖
萌新求助
177069
李白莘莘学子楼主2020/9/6 10:44

调了一上午没调过样例TAT......

上机时间到了,只能求助dalao们帮助一下了(卑微)

代码中注释已加。

目前已知的是:快读没错,链式存图没错,dinic部分没错(dinic是从自己AC代码中快捷键出来的)

orz

#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<iostream>
#define ll long long
#define N 10007
#define inf 214748364
using namespace std;
int read()
{
	int ans=0;
	char ch=getchar(),last=' ';
	while(ch<'0'||ch>'9')last=ch,ch=getchar();
	while(ch>='0'&&ch<='9')ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
	return last=='-'?-ans:ans;
}
struct edg{
	int next,to;
	ll dis;
}edge[50*N];
int r,c,d,n,m,s,t,hea[N],num=1;
int dep[N],h[N],jz[22][22],zbx[N],zby[N],tot;
ll ans;
char getin[22];//输入用字符串数组 
inline void add(int from,int to,ll dis)
{
	num++;
	edge[num].dis=dis;
	edge[num].to=to;
	edge[num].next=hea[from];
	hea[from]=num;
}//链式存图 
int getnumber(int a,int b,int judge)
{
	if(!judge)
	{
		return (a-1)*c+b;//0代表入点 
	}
	return (a-1)*c+b+r*c;//1代表出点 
}//作用:通过横坐标(a),纵坐标(b)来确定对应的图中的点的编号是多少。 
double diss(double x1,double y1,double x2,double y2)
{
	return (y2-y1)*(y2-y1)+(x2-x1)*(x2-x1);
}
//计算长度函数 
inline int bfs()//dinic
{
	queue<int> q;
	for(int i=1;i<=n;i++)
	{
		dep[i]=inf;
	}
	h[s]=hea[s];
	q.push(s);
	dep[s]=0;
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		for(int i=hea[now];i;i=edge[i].next)
		{
			int v=edge[i].to;
			if(dep[v]==inf&&edge[i].dis>0)
			{
				q.push(v);
				dep[v]=dep[now]+1;
				h[v]=hea[v];
				if(v==t)return 1;
			}
		}
	}
	return 0;
}
ll dfs(int now,ll sum)//dinic
{
	if(now==t)return sum;
	ll nex=0,res=0;
	for(int i=h[now];i&&sum;i=edge[i].next)
	{
		h[now]=i;
		int v=edge[i].to;
		if(edge[i].dis>0&&dep[v]==dep[now]+1)
		{
			nex=dfs(v,min(sum,edge[i].dis));
			if(nex==0)dep[v]=inf;
			edge[i].dis-=nex;
			edge[i^1].dis+=nex;
			res+=nex;
			sum-=nex;
		}
	}
	return res;
}
int main(){
	r=read(),c=read(),d=read();//如题 
	s=0,t=r*c*2+1;//s是源点,t是超级汇点 
	for(int i=1;i<=r;i++)
	{
		cin>>getin;
		for(int j=0;j<c;j++)
		{
			jz[i][j+1]=getin[j]-'0';//jz表示ij位置上的石柱高度 
			if(jz[i][j+1])
			{
				add(getnumber(i,j+1,0),getnumber(i,j+1,1),jz[i][j+1]);//入点向出点连长为石柱高度的边 
				add(getnumber(i,j+1,1),getnumber(i,j+1,0),0);//反向边 
				tot++;
				zbx[tot]=i,zby[tot]=j+1;//记录有高度的石柱 
			}
		}
	}
	for(int i=1;i<=r;i++)
		for(int j=1;j<=c;j++)//判断能否跳出去,如果能,向超级汇点连容量inf的边 
		{
			if(jz[i][j])
			{
				if(i<d||i+d>r||j<d||j+d>c)
				{
					add(getnumber(i,j,1),t,inf);add(t,getnumber(i,j,1),0);
				}
			}
		} 
	for(int i=1;i<=r;i++)//如果有蜥蜴,就从源点连容量为1的边 
	{
		cin>>getin;
		for(int j=0;j<c;j++)
		{
			if(getin[j]=='L')
			{
				add(0,getnumber(i,j+1,0),1);add(getnumber(i,j+1,0),0,0);
				ans++;
			}
		}
	}
	for(int i=1;i<=tot;i++)//计算每一个有高度的石柱能跳到其他那些石柱 
		for(int j=1;j<=tot;j++)
		{
			if(i==j)continue;
			if(diss(zbx[i],zby[i],zbx[j],zby[j])<=(double)d*d)
			{
				add(getnumber(zbx[i],zby[i],1),getnumber(zbx[j],zby[j],0),inf);
				add(getnumber(zbx[j],zby[j],0),getnumber(zbx[i],zby[i],1),0);
			}
		}
		while(bfs())//dinic 
		{
			ans-=dfs(0,inf);
		}
	printf("%lld\n",ans);
	return 0;
	//TAT 
}
2020/9/6 10:44
加载中...