codeforces 78E - Evacuation 最大流
来源:互联网 发布:stc8单片机 编辑:程序博客网 时间:2024/05/20 18:19
不能一一贪心暴搜,因为每个人的决策会对其他人产生影响
必须用能考虑到全局的做法
最大,全局,想到最大流
初始化dp[t][x][y][nx][ny] 表示在t时间内能从(x,y)到达(nx,ny)
有个地方要注意
假如某点在k+1时间之前已经infected,下一步不能取
但刚好在k+1时infected,可以到达
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>using namespace std;#define INF 10000000#define N 210#define M 21000struct Edge{ int v,w;}edge[M];int adj[M],head[N],e;void addedge(int u,int v,int w){ edge[e].v=v;edge[e].w=w;adj[e]=head[u];head[u]=e++; edge[e].v=u;edge[e].w=0;adj[e]=head[v];head[v]=e++;}int S,T;int dist[N],q[N*2],arc[N],gap[N],inq[N],pre[N];int SAP(int s,int t){ memset(arc,-1,sizeof(arc)); memset(pre,-1,sizeof(pre)); int qf=0,qr=0; q[qr++]=t;inq[t]=1;gap[0]++;dist[t]=0; while(qf<qr) { int u=q[qf++]; for(int i=head[u];i!=-1;i=adj[i]) if(!inq[edge[i].v]) { int v=edge[i].v; q[qr++]=v; inq[v]=1; dist[v]=dist[u]+1; gap[dist[v]]++; arc[v]=head[v]; } } int low=INF,u=s,ans=0; pre[s]=s; while(dist[s]<t) { bool flag=false; for(int &i=arc[u];i!=-1;i=adj[i]) if(edge[i].w && dist[edge[i].v]+1==dist[u]) { flag=true; low=min(low,edge[i].w); pre[edge[i].v]=u; u=edge[i].v; if(u==t) { while(u!=s) { u=pre[u]; edge[arc[u]].w-=low; edge[arc[u]^1].w+=low; } ans+=low; low=INF; } break; } if(flag) continue; int mindis=t+1; for(int i=head[u];i!=-1;i=adj[i]) if(edge[i].w && mindis>dist[edge[i].v]) { mindis=dist[edge[i].v]; arc[u]=i; } gap[dist[u]]--; if(gap[dist[u]]==0) return ans; dist[u]=mindis+1; gap[dist[u]]++; u=pre[u]; } return ans;}char str[12][12],str2[12][12];int sci[12][12],ca[12][12],stone[62][12][12];int dp[62][12][12][12][12];int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};int n,t;void expand(){ for(int k=1;k<=t;++k) for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { if(stone[k-1][i][j]==1) stone[k][i][j]=1; else if(stone[k-1][i][j]==2) stone[k][i][j]=2; else { int nx,ny; for(int z=0;z<4;++z) { nx=i+dir[z][0]; ny=j+dir[z][1]; if(nx>=1&&nx<=n&&ny>=1&&ny<=n) { if(stone[k-1][nx][ny]==2) stone[k][i][j]=2; } } } }}int vis[12][12];void dfs(int x,int y,int nowx,int nowy,int k){ vis[nowx][nowy]=1; dp[k][x][y][nowx][nowy]=1; if(k>=t || stone[k][nowx][nowy]) return; int nx,ny; for(int z=0;z<4;++z) { nx=nowx+dir[z][0]; ny=nowy+dir[z][1]; if(nx>=1&&nx<=n&&ny>=1&&ny<=n && !vis[nx][ny]) { if(stone[k][nx][ny]) continue; dfs(x,y,nx,ny,k+1); } }}int main (){ scanf("%d%d",&n,&t); for(int i=1;i<=n;++i) { scanf("%s",str[i]+1); for(int j=1;j<=n;++j) { if(str[i][j]=='Z') stone[0][i][j]=2; else if(str[i][j]=='Y') stone[0][i][j]=1; else sci[i][j]=str[i][j]-'0'; } } for(int i=1;i<=n;++i) { scanf("%s",str2[i]+1); for(int j=1;j<=n;++j) { if(str2[i][j]>='0' && str2[i][j]<='9') ca[i][j]=str2[i][j]-'0'; } } expand(); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(sci[i][j]) { memset(vis,0,sizeof(vis)); dfs(i,j,i,j,0); } for(int k=1;k<=t;++k) for(int x=1;x<=n;++x) for(int y=1;y<=n;++y) for(int nx=1;nx<=n;++nx) for(int ny=1;ny<=n;++ny) { dp[k][x][y][nx][ny]+=dp[k-1][x][y][nx][ny]; } S=0;T=n*n*2+1; memset(head,-1,sizeof(head)); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) addedge(S,(i-1)*n+j,sci[i][j]); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) addedge(n*n+(i-1)*n+j,T,ca[i][j]); for(int x=1;x<=n;++x) for(int y=1;y<=n;++y) for(int nx=1;nx<=n;++nx) for(int ny=1;ny<=n;++ny) if(sci[x][y] && ca[nx][ny]) { if(dp[t][x][y][nx][ny]) addedge((x-1)*n+y,n*n+(nx-1)*n+ny,INF); } int ans=SAP(S,T); printf("%d\n",ans); return 0;}
- codeforces 78E - Evacuation 最大流
- Codeforces 78E Evacuation
- codeforces 546E (最大流)
- POJ3057 Evacuation 最大流+二分答案
- codeforces 277E 最小费用最大流
- codeforces #304 E 546E E. Soldier and Traveling(最大流)
- Codeforces 546E - Soldier and Traveling (最大流)
- Codeforces 546E Soldier and Traveling (最大流)
- Codeforces 546E:士兵的旅行 最大网络流
- Codeforces 546E Soldier and Traveling 最大流 C#实现
- POJ 3057 Evacuation (最大流加边)
- poj3057 Evacuation(二分+最大匹配)
- Codeforces Round #290 (Div. 2) E. Fox And Dinner 网络流 最大流
- Codeforces Round #185 (Div. 1) E.Biologist 最小割最大流
- codeforces 510E Fox And Dinner 奇偶建图+最大流
- Codeforces Round #290 (Div. 2)E. Fox And Dinner——最大流 奇偶建图
- CodeForces 546E - Soldier and Traveling(最大流+输出边流量)
- Codeforces Round #304 (Div. 2) E - Soldier and Traveling 最大流 isap
- android捕获ListView中每个item点击事件
- div width=auto 与 width = 100% 区别
- struts.xml配置json
- js笔记之一
- jstring与c++字符串类型转换函数
- codeforces 78E - Evacuation 最大流
- SQL中 In 、Not In 、Exists、Not Exists 用法和差别
- jquery获取 select option 的文本与值value
- Leetcode: Sum Root to Leaf Number
- openflow协议
- 遍历二叉树-递归和非递归算法
- C# MediaPlayer的详细用法
- 08-CMD_if命令讲解
- MFC中用ado访问SQL Server 2005数据库