UVA Live 6557 Stampede! (uestc oj 871) 最大流+二分
2017-06-29 13:03
477 查看
E - Stampede!
Time Limit: 3000/1000MS (Java/Others)
Memory Limit: 131072/131072KB (Java/Others)
You have an n×n game
board. Some squares contain obstacles, except the left- and right-most columns which are obstacle-free.
The left-most column is filled with your n pieces, 1 per
row. Your goal is to move all your pieces to the right-most column as quickly
as possible.
In a given turn, you can move each piece
N,
S,
E,
or
Wone space, or leave that piece in place.
A piece cannot move onto a square containing an obstacle, nor may two pieces move to the same square on the same turn.
All pieces move simultaneously, so one may move to a location currently occupied by another piece so long as that piece itself moves
elsewhere at the same time.
Given n and
the obstacles, determine the fewest number of turns needed to get all your pieces to the right-hand side of the board.
Input
Each test case starts with a positive integer n indicatingthe size of the game board, with n≤25.
Following this will be n lines
containing
ncharacters
each.
If the jth character
in the ith line
is an
X, then there is an obstacle in board location i,j;
otherwise this character will be a
.indicating
no obstacle.
There will never be an obstacle in the 0th or (n−1)st column
and there will always be at least one obstacle-free path between these
two columns.
A line containing a single 0 will
terminate input.
Output
For each test case output the minimum number of turns to move all the pieces from the left side of the board to the right side.
Sample input and output
Sample Input | Sample Output |
---|---|
5 ..... .X... ...X. ..X.. ..... 5 .X... .X... .X... .XXX. ..... 0 | Case 1: 6 Case 2: 8 |
Source
2013 East Central Regional Contest给你一个地图,.表示可以走,X表示不能走,左边n个点开始时有n个人,问从左边n个点走到右边n个点最短时间是多少。
每个点任意时刻仅可容纳一个人。
网络流。
左边n个点到右边n个点,显然是一个多源点多汇点题目。题目要求每个点任意时刻只能有一个人,那么我们建图时可以二分时间t,
将一个点拆成t+1个点,分别表示时刻0,1,...t的该点。之后,根据所给地图建图,跑最大流就好了。
时限应该是20s,坑爹的oj...害的我跑到codeforces gym去测这题
#include <cstdio> #include <iostream> #include <queue> #include <vector> #include <string.h> using namespace std; const int maxn=500005,maxk=5000005,inf=0x3f3f3f3f; int num=0,current[maxn],head[maxn],r[maxn],dirx[4],diry[4]; char map[28][28]; struct Edge{ int to,flow,pre; } edge[maxk]; void addedge(int from,int to,int flow) { edge[num]=(Edge){to,flow,head[from]}; head[from]=num++; edge[num]=(Edge){from,0,head[to]}; head[to]=num++; } bool bfs(int n) { queue<int> q; memset(r,-1,sizeof(r)); q.push(0); r[0]=0; while (!q.empty()) { int now=q.front(); q.pop(); for (int i=head[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; if (r[to]==-1&&edge[i].flow>0) { r[to]=r[now]+1; q.push(to); } } } return r !=-1; } int dfs(int now,int flow,int des) { if (now==des) return flow; int f; for (int i=current[now];i!=-1;i=edge[i].pre) { int to=edge[i].to; current[now]=i; if (edge[i].flow>0&&r[to]==r[now]+1) { if (f=dfs(to,min(flow,edge[i].flow),des)) { edge[i].flow-=f; edge[i^1].flow+=f; return f; } } } return 0; } int dinic(int n) { int i,f,sum=0; while (bfs(n)) { memcpy(current,head,sizeof(head)); while (f=dfs(0,inf,n)) sum+=f; } // cout << n << ' ' << sum << endl; return sum; } void buildgraph(int mid,int n) { num=0; memset(head,-1,sizeof(head)); int i,k=0,l,j,m; for (i=1;i<=n;i++) { addedge(0,(i-1)*mid*n+1,1); addedge(i*n*mid,n*n*mid+1,1); for (j=1;j<=n;j++) { k++; for (l=1;l<mid;l++) { addedge((k-1)*mid+l,(k-1)*mid+l+1,1); if (map[i][j-1]=='.') for (m=0;m<4;m++) { int nowx=i+dirx[m],nowy=j+diry[m]; if (map[nowx][nowy-1]=='.'&&nowx>0&&nowx<=n&&nowy>0&&nowy<=n) { int u=(nowx-1)*n+nowy; addedge((k-1)*mid+l,(u-1)*mid+l+1,1); } } } } } } int solve(int n) { int l=1,r=n*n+5,mid,ans=-1; while (l<=r) { mid=(l+r)/2; buildgraph(mid,n); if (dinic(mid*n*n+1)>=n) { ans=mid; r=mid-1; } else l=mid+1; } return ans-1; } int main() { int n,t=0,i; scanf("%d",&n); dirx[0]=dirx[1]=diry[2]=diry[3]=0; dirx[2]=1;dirx[3]=-1; diry[0]=1;diry[1]=-1; while (n) { t++; for (i=1;i<=n;i++) { scanf("%s",map[i]); } int ans=solve(n); printf("Case %d: %d\n",t,ans); scanf("%d",&n); } return 0; }
相关文章推荐
- UVALive 6557 Stampede!(最大流)
- UVa live6492Welcome Party(二分最大匹配之最小点覆盖)
- UVALive - 3268 Jamie's Contact Groups(二分+最大流)
- uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。
- (beginer) 网络流(最大流+二分) UVA 1345 - Jamie\'s Contact Groups
- UVa live3415Guardian of Decency(二分最大匹配之最大独立点集)
- UVA Live 6122 || UESTC OJ 2326 枚举+排序+LIS
- UVA-1345 - Jamie's Contact Groups(最大流+二分)
- UVAlive--4529--Dangerous Tunnels(二分+拆点最大流)
- uva 1345 Jamie's Contact Groups (最大流+二分)
- Risk UVA - 12264 拆点法+最大流+二分 最少流量的节点流量尽量多。
- UVaLive LA 4726 UVa 1451 - Average (子序列最大平均数 数形结合 斜率优化 单调队列)
- UVALive 5903 Piece it together 二分匹配,拆点 难度:1
- UVALive 3890 Most Distant Point from the Sea(凸包最大内接圆)
- UVA 11419 SAM I AM(最大二分匹配&最小点覆盖:König定理)
- UVALive 7037 (最大密度子图 网络流)
- UVALive - 3506 4 Values whose Sum is 0 二分
- uvaLive 2387 - Gene Assembly 最大区间调度问题
- 二分搜索 UVALive 6076 Yukari's Birthday (12长春K)
- POj 2002 UVALive - 3047 C - Squares 【计算几何+二分求解】