loj 1150(spfa预处理+二分+最大匹配)
来源:互联网 发布:java编写小程序 编辑:程序博客网 时间:2024/06/14 03:33
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26864
思路:首先是spfa预处理出每个'G'到'H'的最短距离,然后就是二分最大距离,最大匹配验证即可。
PS:这道题一开始没什么思路,然后想先最简单的spfa预处理写一下吧,然后写着写着就突然豁然开朗,有思路了!然后就AC了!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 #define MAXN 55 9 #define inf 1<<30 10 #define FILL(a,b) memset(a,b,sizeof(a)) 11 12 vector<pair<int,int> >g,h; 13 14 int n,dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 15 int dist[MAXN][MAXN],dd[MAXN][MAXN]; 16 bool mark[MAXN][MAXN]; 17 char map[MAXN][MAXN]; 18 19 void spfa(int vs) 20 { 21 FILL(mark,false); 22 for(int i=0;i<MAXN;i++) 23 for(int j=0;j<MAXN;j++)dd[i][j]=inf; 24 queue<pair<int,int> >que; 25 que.push(make_pair(g[vs].first,g[vs].second)); 26 dd[g[vs].first][g[vs].second]=0; 27 while(!que.empty()){ 28 pair<int,int>p=que.front(); 29 que.pop(); 30 mark[p.first][p.second]=false; 31 for(int i=0;i<4;i++){ 32 int x=p.first+dir[i][0],y=p.second+dir[i][1]; 33 if(x>=0&&x<n&&y>=0&&y<n&&map[x][y]!='#'){ 34 if(dd[p.first][p.second]+1<dd[x][y]){ 35 dd[x][y]=dd[p.first][p.second]+1; 36 if(!mark[x][y]){ 37 mark[x][y]=true; 38 que.push(make_pair(x,y)); 39 } 40 } 41 } 42 } 43 } 44 } 45 46 vector<int>gg[MAXN]; 47 void Build(int limit) 48 { 49 for(int i=0;i<MAXN;i++)gg[i].clear(); 50 for(int i=0;i<g.size();i++){ 51 for(int j=0;j<h.size();j++){ 52 if(dist[i][j]<=limit)gg[i].push_back(j); 53 } 54 } 55 } 56 57 int ly[MAXN]; 58 bool vis[MAXN]; 59 60 int dfs(int u) 61 { 62 for(int i=0;i<gg[u].size();i++){ 63 int v=gg[u][i]; 64 if(!vis[v]){ 65 vis[v]=true; 66 if(ly[v]==-1||dfs(ly[v])){ 67 ly[v]=u; 68 return 1; 69 } 70 } 71 } 72 return 0; 73 } 74 75 int MaxMatch() 76 { 77 int res=0; 78 FILL(ly,-1); 79 for(int i=0;i<g.size();i++){ 80 FILL(vis,false); 81 res+=dfs(i); 82 } 83 return res; 84 } 85 86 int main() 87 { 88 int _case,t=1; 89 scanf("%d",&_case); 90 while(_case--){ 91 scanf("%d",&n); 92 g.clear(); 93 h.clear(); 94 for(int i=0;i<n;i++)scanf("%s",map[i]); 95 for(int i=0;i<n;i++){ 96 for(int j=0;j<n;j++){ 97 if(map[i][j]=='G')g.push_back(make_pair(i,j)); 98 else if(map[i][j]=='H')h.push_back(make_pair(i,j)); 99 }100 }101 for(int i=0;i<MAXN;i++)102 for(int j=0;j<MAXN;j++)dist[i][j]=inf;103 for(int i=0;i<g.size();i++){104 spfa(i);105 for(int j=0;j<h.size();j++){106 if(dd[h[j].first][h[j].second]!=inf)dist[i][j]=min(dist[i][j],2*dd[h[j].first][h[j].second]+2);107 }108 }109 int low=inf,high=0,mid,ans=inf;110 for(int i=0;i<g.size();i++){111 for(int j=0;j<h.size();j++){112 if(dist[i][j]!=inf){113 low=min(low,dist[i][j]);114 high=max(high,dist[i][j]);115 }116 }117 }118 while(low<=high){119 mid=(low+high)>>1;120 Build(mid);121 if(MaxMatch()==(int)h.size()){122 ans=mid;123 high=mid-1;124 }else125 low=mid+1;126 }127 printf("Case %d: ",t++);128 if(ans!=inf){129 printf("%d\n",ans);130 }else131 puts("Vuter Dol Kupokat");132 }133 return 0;134 }
0 0
- loj 1150(spfa预处理+二分+最大匹配)
- loj 1316(spfa预处理+状压dp)
- LOJ 1201 - A Perfect Murder(二分匹配 最大独立集)
- loj 1156(二分+最大流)
- loj 1167(二分+最大流)
- 最大二分匹配【转】
- poj1274 最大二分匹配
- 最大二分匹配
- 二分图最大匹配
- 二分图最大匹配 。
- 二分图最大匹配
- 二分图最大匹配
- 二分图最大匹配
- 二分图最大匹配
- 二分图 最大匹配
- 二分图最大匹配
- 二分图最大匹配
- 最大二分匹配
- loj 1018(状压dp+记忆化搜索)
- loj 1021(状压dp+记忆化搜索)
- loj 1025(记忆化搜索)
- loj 1155(最大流)
- loj 1156(二分+最大流)
- loj 1150(spfa预处理+二分+最大匹配)
- loj 1031(区间dp+记忆化搜索)
- loj 1032(数位dp)
- loj 1167(二分+最大流)
- loj 1036(dp)
- loj 1037(状压dp)
- loj 1038(dp求期望)
- hdu 4281(MTSP)
- loj 1201(最大独立集)