您的位置:首页 > 其它

CodeForces 173B Chamber of Secrets 二分图+最短路

2016-06-01 13:21 519 查看

题目链接:

http://codeforces.com/problemset/problem/173/B

题意:

给你一个n*m的地图,现在有一束激光从左上角往左边射出,每遇到‘#’,你可以选择光线往四个方向射出,或者什么都不做,问最少需要多少个‘#’往四个方向射出才能使关系在n行往右边射出。

题解:

以行和列建二分图,如果str[i][j]=='#',则从i节点到j节点建一条双向边,权值都为1。然后对二分图跑一遍最短路。

代码:

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn = 2222;

vector<int> G[maxn];
char str[maxn][maxn];
int n, m;

int inq[maxn], d[maxn];
int spfa() {
queue<int> Q;
memset(inq, 0, sizeof(inq));
memset(d, 0x7f, sizeof(d)); int ma = d[0];
d[1] = 0; inq[1] = 1; Q.push(1);
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (d[v] > d[u] + 1) {
d[v] = d[u] + 1;
if (!inq[v]) inq[v]=1,Q.push(v);
}
}
}
if (d
>= ma) return -1;
return d
;
}

void init() {
for (int i = 0; i <= n + m + 1; i++) G[i].clear();
}

int main() {
while (scanf("%d%d", &n, &m) == 2 && n) {
init();
for (int i = 1; i <= n; i++) scanf("%s", str[i] + 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (str[i][j] == '#') {
G[i].push_back(j + n);
G[j + n].push_back(i);
}
}
}
int ans = spfa();
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: