POJ 3057 二分图最大匹配
来源:互联网 发布:人工智能应用案例 编辑:程序博客网 时间:2024/06/04 08:33
比较难想的一道二分图。
考虑这么建图。
时间和门的二元组为二分图的x集合的元素,每个人为y集合的元素,连边就表示,这段时间内此门能让此人过。
让时间从1开始递增,每次寻找x集合和y集合的最大匹配,当最大匹配等于人数时,此时间满足所有人都离开屋子。
每次找最大匹配可以在上一个时间的残余图上寻找增广路,速度还是挺快的。
#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#include<vector>#include<cstdlib>using namespace std;#define MAX_V 5000#define INF 0x3f3f3f3ftypedef pair<int,int> P;bool vis[MAX_V];int match[MAX_V];bool G[MAX_V][MAX_V];int x_cnt,y_cnt;bool find_path(int u){ for(int i=0;i<y_cnt;i++) { if(!vis[i]&&G[u][i]) { vis[i]=1; if(match[i]==-1||find_path(match[i])) { match[i]=u; return true; } } } return false;}int N,M;char MAP[20][20];int DIS[20][20][20][20];int dx[4]={1,0,-1,0};int dy[4]={0,1,0,-1};vector<P> DOOR;vector<P> MAN;void bfs(int u,int v,int d[20][20]){ queue<P> Q; d[u][v]=0; Q.push(P(u,v)); while(!Q.empty()) { P now=Q.front(); Q.pop(); for(int i=0;i<4;i++) { int tx=now.first+dx[i],ty=now.second+dy[i]; if(tx>=0&&tx<N&&ty>=0&&ty<M&&MAP[tx][ty]=='.'&&d[tx][ty]==-1) { d[tx][ty]=d[now.first][now.second]+1; Q.push(P(tx,ty)); } } }}int slove(){ memset(G,0,sizeof(G)); memset(match,-1,sizeof(match)); x_cnt=DOOR.size(); y_cnt=MAN.size(); int res=0; for(int T=0;T<N*M;T++) { for(int i=0;i<DOOR.size();i++) { for(int j=0;j<MAN.size();j++) { int doorx=DOOR[i].first,doory=DOOR[i].second; int manx=MAN[j].first,many=MAN[j].second; if(DIS[doorx][doory][manx][many]!=-1&&DIS[doorx][doory][manx][many]<=T+1&&G[i][j]==0) { G[i][j]=1; } } } for(int i=0;i<x_cnt;i++) { memset(vis,0,sizeof(vis)); if(find_path(i)) res++; } if(res==MAN.size()) return T+1; } return -1;}int main(){ int t; scanf("%d",&t); while(t--) { DOOR.clear(); MAN.clear(); scanf("%d%d",&N,&M); for(int i=0;i<N;i++) { scanf("%s",MAP[i]); } memset(DIS,-1,sizeof(DIS)); for(int i=0;i<N;i++) { for(int j=0;j<M;j++) { if(MAP[i][j]=='D') { DOOR.push_back(P(i,j)); bfs(i,j,DIS[i][j]); } else if(MAP[i][j]=='.') MAN.push_back(P(i,j)); } } int ans=slove(); if(ans==-1) printf("impossible\n"); else printf("%d\n",ans); } return 0;}
0 0
- POJ 3057 二分图最大匹配
- POJ 3057 最大二分匹配+bfs + 二分
- poj 3057 Evacuation 二分图最大匹配 最短路
- POJ 1274 二分图最大匹配
- POJ 1469 二分图最大匹配
- POJ 2239 二分图最大匹配
- Asteroids(poj 3041,二分图最大匹配)
- poj 1274 二分图 最大匹配
- poj 1469 二分图最大匹配
- POJ 1469二分图最大匹配
- poj 1274 二分图最大匹配
- POJ 1469 二分图最大匹配 COURSES
- poj 2446 二分图 最大匹配
- poj 2536 二分图 最大匹配
- POJ 3692 二分图最大匹配
- Muddy Fields+POJ+二分图最大匹配
- POJ 1469 COURSES(二分图最大匹配)
- POJ 2446 Chessboard(二分图最大匹配)
- zip 和 sourceCRT
- ios开发之 全局变量设置
- C语言 判断两个矩形是否相交
- ExecuteNonQuery()返回-1的问题及解决
- 浅论Maven和Git的原理及展示其与Eclipse的集成
- POJ 3057 二分图最大匹配
- Mysql时间戳
- python把不在同一个目录下的模块添加到当前目录
- 广播的远距离传送
- Deepin 下交换 CapsLock和Ctrl
- 单例(Singleton)模式
- git和maven的必要性
- C#默认参数
- Qt样式表实例