这咋错了,WA 70分求助,是和题解不大一样的拆点做法
查看原帖
这咋错了,WA 70分求助,是和题解不大一样的拆点做法
141978
封禁用户楼主2020/5/7 19:49

枚举日期day,把每一天拆成day个点跑网络流,具体做法和星际转移问题差不多

我看了题解一圈发现全是什么二分答案+拆门,感觉写起来有点麻烦就懒得写了

#include<bits/stdc++.h>
using namespace std;
const int N=1500000+5,inf=0x3f3f3f3f;
struct edge{
	int to,nxt,val,cost;
}e[N<<5];
int head[N],cnt,maxflow,vis[N],dis[N],nxt[N];
int s,t;
void add_edge(int x,int y,int z){
	e[++cnt].to=y; e[cnt].val=z; e[cnt].nxt=head[x]; head[x]=cnt;
}
void add(int x,int y,int z){
	add_edge(x,y,z);
	add_edge(y,x,0);
}
queue<int> q;
bool spfa(){
	memset(dis,0x3f,sizeof(dis));
//	cout<<dis[0]<<" "<<-inf<<endl;
	dis[s]=0; q.push(s);
	while(!q.empty()){
		int u=q.front(); q.pop(); vis[u]=0;
		for(int i=head[u];i;i=e[i].nxt)
			if(e[i].val && dis[e[i].to]>dis[u]+1){
				dis[e[i].to]=dis[u]+1;
				if(!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
			}
	}
	return (dis[t])^inf;
}
bool flag[N];
int dfs(int u,int limit){
	if(u==t) return limit;
	int flow=0;
	for(int i=head[u];i&&limit;i=e[i].nxt)
		if(e[i].val &&dis[e[i].to]==dis[u]+1){
			int k=dfs(e[i].to,min(limit,e[i].val));
			if(k>0){
				e[i].val-=k; e[i^1].val+=k;
				limit-=k; flow+=k;			
			}
		}
	if(!flow) dis[u]=inf;
	return flow;
}
void Dinic(){
	while(spfa()) maxflow+=dfs(s,inf);
}
int a[105][105],n,m;
int num(int i,int j,int k){
	return (i-1)*m+j+k*n*m;
}
int di[4]={0,1,0,-1};
int dj[4]={1,0,-1,0};
char ch;
int main(){
	cin>>n>>m;
	int tot=0;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j){
			cin>>ch;
			if(ch=='.') ++tot,a[i][j]=0;
			if(ch=='X') a[i][j]=1;
			if(ch=='D') a[i][j]=2; 
		}
	int day=0;
	s=0; t=1145140;
	while(day<500){
		if(day==0){
			for(int i=1;i<=n;++i)
				for(int j=1;j<=m;++j)
					if(a[i][j]==0) add(s,num(i,j,day),1);
		}
		for(int i=1;i<=n;++i)
			for(int j=1;j<=m;++j)
				if(a[i][j]==2) add(num(i,j,day),t,1);		
		if(day){
			for(int i=1;i<=n;++i)
				for(int j=1;j<=m;++j){
					if(a[i][j]==0) add(num(i,j,day-1),num(i,j,day),inf);
					for(int k=0;k<4;++k){
						int ti=i+di[k],tj=j+dj[k];
						if(1<=ti&&ti<=n&&1<=tj&&tj<=m&&a[ti][tj]!=1) add(num(i,j,day-1),num(ti,tj,day),1);
					}
				}
		}
		Dinic();
		if(maxflow>=tot) return cout<<day,0; 
		++day;
	}
	cout<<"impossible";
	return 0;
}
2020/5/7 19:49
加载中...